Merge branch 'openfbx_fixes' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-openfbx_fixes
This commit is contained in:
@@ -73,6 +73,16 @@ namespace FlaxEditor.Content
|
|||||||
return targetLocation.CanHaveAssets;
|
return targetLocation.CanHaveAssets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool CanReimport(ContentItem item)
|
||||||
|
{
|
||||||
|
if (item is not PrefabItem prefabItem)
|
||||||
|
return base.CanReimport(item);
|
||||||
|
|
||||||
|
var prefab = FlaxEngine.Content.Load<Prefab>(prefabItem.ID);
|
||||||
|
return prefab.GetDefaultInstance().GetScript<ModelPrefab>() != null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Create(string outputPath, object arg)
|
public override void Create(string outputPath, object arg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -309,6 +309,23 @@ namespace FlaxEditor.Windows
|
|||||||
{
|
{
|
||||||
if (selection[i] is BinaryAssetItem binaryAssetItem)
|
if (selection[i] is BinaryAssetItem binaryAssetItem)
|
||||||
Editor.ContentImporting.Reimport(binaryAssetItem);
|
Editor.ContentImporting.Reimport(binaryAssetItem);
|
||||||
|
else if (selection[i] is PrefabItem prefabItem)
|
||||||
|
{
|
||||||
|
var prefab = FlaxEngine.Content.Load<Prefab>(prefabItem.ID);
|
||||||
|
var modelPrefab = prefab.GetDefaultInstance().GetScript<ModelPrefab>();
|
||||||
|
if (!modelPrefab)
|
||||||
|
continue;
|
||||||
|
var importPath = modelPrefab.ImportPath;
|
||||||
|
var editor = Editor.Instance;
|
||||||
|
if (editor.ContentImporting.GetReimportPath("Model Prefab", ref importPath))
|
||||||
|
continue;
|
||||||
|
var folder = editor.ContentDatabase.Find(Path.GetDirectoryName(prefab.Path)) as ContentFolder;
|
||||||
|
if (folder == null)
|
||||||
|
continue;
|
||||||
|
var importOptions = modelPrefab.ImportOptions;
|
||||||
|
importOptions.Type = FlaxEngine.Tools.ModelTool.ModelType.Prefab;
|
||||||
|
editor.ContentImporting.Import(importPath, folder, true, importOptions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,12 @@
|
|||||||
#define USE_MIKKTSPACE 1
|
#define USE_MIKKTSPACE 1
|
||||||
#include "ThirdParty/MikkTSpace/mikktspace.h"
|
#include "ThirdParty/MikkTSpace/mikktspace.h"
|
||||||
#if USE_ASSIMP
|
#if USE_ASSIMP
|
||||||
#define USE_SPARIAL_SORT 1
|
#define USE_SPATIAL_SORT 1
|
||||||
#define ASSIMP_BUILD_NO_EXPORT
|
#define ASSIMP_BUILD_NO_EXPORT
|
||||||
#include "Engine/Tools/ModelTool/SpatialSort.h"
|
#include "Engine/Tools/ModelTool/SpatialSort.h"
|
||||||
//#include <ThirdParty/assimp/SpatialSort.h>
|
//#include <ThirdParty/assimp/SpatialSort.h>
|
||||||
#else
|
#else
|
||||||
#define USE_SPARIAL_SORT 0
|
#define USE_SPATIAL_SORT 0
|
||||||
#endif
|
#endif
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
@@ -155,18 +155,18 @@ bool MeshData::GenerateLightmapUVs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32 FindVertex(const MeshData& mesh, int32 vertexIndex, int32 startIndex, int32 searchRange, const Array<int32>& mapping
|
int32 FindVertex(const MeshData& mesh, int32 vertexIndex, int32 startIndex, int32 searchRange, const Array<int32>& mapping
|
||||||
#if USE_SPARIAL_SORT
|
#if USE_SPATIAL_SORT
|
||||||
, const Assimp::SpatialSort& spatialSort
|
, const Assimp::SpatialSort& spatialSort
|
||||||
, std::vector<unsigned int>& sparialSortCache
|
, std::vector<unsigned int>& spatialSortCache
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const float uvEpsSqr = (1.0f / 250.0f) * (1.0f / 250.0f);
|
const float uvEpsSqr = (1.0f / 250.0f) * (1.0f / 250.0f);
|
||||||
|
|
||||||
#if USE_SPARIAL_SORT
|
#if USE_SPATIAL_SORT
|
||||||
const Float3 vPosition = mesh.Positions[vertexIndex];
|
const Float3 vPosition = mesh.Positions[vertexIndex];
|
||||||
spatialSort.FindPositions(*(aiVector3D*)&vPosition, 1e-4f, sparialSortCache);
|
spatialSort.FindPositions(*(aiVector3D*)&vPosition, 1e-5f, spatialSortCache);
|
||||||
if (sparialSortCache.empty())
|
if (spatialSortCache.empty())
|
||||||
return INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
|
|
||||||
const Float2 vUV = mesh.UVs.HasItems() ? mesh.UVs[vertexIndex] : Float2::Zero;
|
const Float2 vUV = mesh.UVs.HasItems() ? mesh.UVs[vertexIndex] : Float2::Zero;
|
||||||
@@ -177,9 +177,9 @@ int32 FindVertex(const MeshData& mesh, int32 vertexIndex, int32 startIndex, int3
|
|||||||
|
|
||||||
const int32 end = startIndex + searchRange;
|
const int32 end = startIndex + searchRange;
|
||||||
|
|
||||||
for (size_t i = 0; i < sparialSortCache.size(); i++)
|
for (size_t i = 0; i < spatialSortCache.size(); i++)
|
||||||
{
|
{
|
||||||
const int32 v = sparialSortCache[i];
|
const int32 v = spatialSortCache[i];
|
||||||
if (v < startIndex || v >= end)
|
if (v < startIndex || v >= end)
|
||||||
continue;
|
continue;
|
||||||
#else
|
#else
|
||||||
@@ -247,11 +247,11 @@ void MeshData::BuildIndexBuffer()
|
|||||||
mapping.Resize(vertexCount);
|
mapping.Resize(vertexCount);
|
||||||
int32 newVertexCounter = 0;
|
int32 newVertexCounter = 0;
|
||||||
|
|
||||||
#if USE_SPARIAL_SORT
|
#if USE_SPATIAL_SORT
|
||||||
// Set up a SpatialSort to quickly find all vertices close to a given position
|
// Set up a SpatialSort to quickly find all vertices close to a given position
|
||||||
Assimp::SpatialSort vertexFinder;
|
Assimp::SpatialSort vertexFinder;
|
||||||
vertexFinder.Fill((const aiVector3D*)Positions.Get(), vertexCount, sizeof(Float3));
|
vertexFinder.Fill((const aiVector3D*)Positions.Get(), vertexCount, sizeof(Float3));
|
||||||
std::vector<unsigned int> sparialSortCache;
|
std::vector<unsigned int> spatialSortCache;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Build index buffer
|
// Build index buffer
|
||||||
@@ -259,8 +259,8 @@ void MeshData::BuildIndexBuffer()
|
|||||||
{
|
{
|
||||||
// Find duplicated vertex before the current one
|
// Find duplicated vertex before the current one
|
||||||
const int32 reuseVertexIndex = FindVertex(*this, vertexIndex, 0, vertexIndex, mapping
|
const int32 reuseVertexIndex = FindVertex(*this, vertexIndex, 0, vertexIndex, mapping
|
||||||
#if USE_SPARIAL_SORT
|
#if USE_SPATIAL_SORT
|
||||||
, vertexFinder, sparialSortCache
|
, vertexFinder, spatialSortCache
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
if (reuseVertexIndex == INVALID_INDEX)
|
if (reuseVertexIndex == INVALID_INDEX)
|
||||||
@@ -376,7 +376,7 @@ bool MeshData::GenerateNormals(float smoothingAngle)
|
|||||||
Float3::Max(max, v3, max);
|
Float3::Max(max, v3, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SPARIAL_SORT
|
#if USE_SPATIAL_SORT
|
||||||
// Set up a SpatialSort to quickly find all vertices close to a given position
|
// Set up a SpatialSort to quickly find all vertices close to a given position
|
||||||
Assimp::SpatialSort vertexFinder;
|
Assimp::SpatialSort vertexFinder;
|
||||||
vertexFinder.Fill((const aiVector3D*)Positions.Get(), vertexCount, sizeof(Float3));
|
vertexFinder.Fill((const aiVector3D*)Positions.Get(), vertexCount, sizeof(Float3));
|
||||||
@@ -399,7 +399,7 @@ bool MeshData::GenerateNormals(float smoothingAngle)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Get all vertices that share this one
|
// Get all vertices that share this one
|
||||||
#if USE_SPARIAL_SORT
|
#if USE_SPATIAL_SORT
|
||||||
vertexFinder.FindPositions(*(aiVector3D*)&Positions[i], posEpsilon, verticesFound);
|
vertexFinder.FindPositions(*(aiVector3D*)&Positions[i], posEpsilon, verticesFound);
|
||||||
const int32 verticesFoundCount = (int32)verticesFound.size();
|
const int32 verticesFoundCount = (int32)verticesFound.size();
|
||||||
#else
|
#else
|
||||||
@@ -429,7 +429,7 @@ bool MeshData::GenerateNormals(float smoothingAngle)
|
|||||||
for (int32 i = 0; i < vertexCount; i++)
|
for (int32 i = 0; i < vertexCount; i++)
|
||||||
{
|
{
|
||||||
// Get all vertices that share this one
|
// Get all vertices that share this one
|
||||||
#if USE_SPARIAL_SORT
|
#if USE_SPATIAL_SORT
|
||||||
vertexFinder.FindPositions(*(aiVector3D*)&Positions[i], posEpsilon, verticesFound);
|
vertexFinder.FindPositions(*(aiVector3D*)&Positions[i], posEpsilon, verticesFound);
|
||||||
const int32 verticesFoundCount = (int32)verticesFound.size();
|
const int32 verticesFoundCount = (int32)verticesFound.size();
|
||||||
#else
|
#else
|
||||||
@@ -623,7 +623,7 @@ bool MeshData::GenerateTangents(float smoothingAngle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SPARIAL_SORT
|
#if USE_SPATIAL_SORT
|
||||||
// Set up a SpatialSort to quickly find all vertices close to a given position
|
// Set up a SpatialSort to quickly find all vertices close to a given position
|
||||||
Assimp::SpatialSort vertexFinder;
|
Assimp::SpatialSort vertexFinder;
|
||||||
vertexFinder.Fill((const aiVector3D*)Positions.Get(), vertexCount, sizeof(Float3));
|
vertexFinder.Fill((const aiVector3D*)Positions.Get(), vertexCount, sizeof(Float3));
|
||||||
@@ -648,7 +648,7 @@ bool MeshData::GenerateTangents(float smoothingAngle)
|
|||||||
closeVertices.Clear();
|
closeVertices.Clear();
|
||||||
|
|
||||||
// Find all vertices close to that position
|
// Find all vertices close to that position
|
||||||
#if USE_SPARIAL_SORT
|
#if USE_SPATIAL_SORT
|
||||||
vertexFinder.FindPositions(*(aiVector3D*)&origPos, posEpsilon, verticesFound);
|
vertexFinder.FindPositions(*(aiVector3D*)&origPos, posEpsilon, verticesFound);
|
||||||
const int32 verticesFoundCount = (int32)verticesFound.size();
|
const int32 verticesFoundCount = (int32)verticesFound.size();
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
#include "Engine/Core/Math/Mathd.h"
|
#include "Engine/Core/Math/Mathd.h"
|
||||||
#include "Engine/Core/Math/Matrix.h"
|
#include "Engine/Core/Math/Matrix.h"
|
||||||
|
#include "Engine/Core/Math/Plane.h"
|
||||||
#include "Engine/Core/Collections/Sorting.h"
|
#include "Engine/Core/Collections/Sorting.h"
|
||||||
#include "Engine/Platform/FileSystem.h"
|
#include "Engine/Platform/FileSystem.h"
|
||||||
#include "Engine/Tools/TextureTool/TextureTool.h"
|
#include "Engine/Tools/TextureTool/TextureTool.h"
|
||||||
@@ -49,7 +50,7 @@ Quaternion ToQuaternion(const ofbx::Quat& v)
|
|||||||
return Quaternion((float)v.x, (float)v.y, (float)v.z, (float)v.w);
|
return Quaternion((float)v.x, (float)v.y, (float)v.z, (float)v.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix ToMatrix(const ofbx::Matrix& mat)
|
Matrix ToMatrix(const ofbx::DMatrix& mat)
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
for (int32 i = 0; i < 16; i++)
|
for (int32 i = 0; i < 16; i++)
|
||||||
@@ -416,7 +417,7 @@ void ProcessNodes(OpenFbxImporterData& data, const ofbx::Object* aNode, int32 pa
|
|||||||
Matrix GetOffsetMatrix(OpenFbxImporterData& data, const ofbx::Mesh* mesh, const ofbx::Object* node)
|
Matrix GetOffsetMatrix(OpenFbxImporterData& data, const ofbx::Mesh* mesh, const ofbx::Object* node)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
auto* skin = mesh ? mesh->getGeometry()->getSkin() : nullptr;
|
auto* skin = mesh ? mesh->getSkin() : nullptr;
|
||||||
if (skin)
|
if (skin)
|
||||||
{
|
{
|
||||||
for (int i = 0, c = skin->getClusterCount(); i < c; i++)
|
for (int i = 0, c = skin->getClusterCount(); i < c; i++)
|
||||||
@@ -445,7 +446,7 @@ Matrix GetOffsetMatrix(OpenFbxImporterData& data, const ofbx::Mesh* mesh, const
|
|||||||
|
|
||||||
bool IsMeshInvalid(const ofbx::Mesh* aMesh)
|
bool IsMeshInvalid(const ofbx::Mesh* aMesh)
|
||||||
{
|
{
|
||||||
return aMesh->getGeometry()->getVertexCount() == 0;
|
return aMesh->getGeometryData().getPositions().count == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImportBones(OpenFbxImporterData& data, String& errorMsg)
|
bool ImportBones(OpenFbxImporterData& data, String& errorMsg)
|
||||||
@@ -455,8 +456,7 @@ bool ImportBones(OpenFbxImporterData& data, String& errorMsg)
|
|||||||
for (int i = 0; i < meshCount; i++)
|
for (int i = 0; i < meshCount; i++)
|
||||||
{
|
{
|
||||||
const auto aMesh = data.Scene->getMesh(i);
|
const auto aMesh = data.Scene->getMesh(i);
|
||||||
const auto aGeometry = aMesh->getGeometry();
|
const ofbx::Skin* skin = aMesh->getSkin();
|
||||||
const ofbx::Skin* skin = aGeometry->getSkin();
|
|
||||||
if (skin == nullptr || IsMeshInvalid(aMesh))
|
if (skin == nullptr || IsMeshInvalid(aMesh))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -524,56 +524,202 @@ bool ImportBones(OpenFbxImporterData& data, String& errorMsg)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh* aMesh, MeshData& mesh, String& errorMsg, int32 triangleStart, int32 triangleEnd)
|
int Triangulate(const ofbx::GeometryData& geom, const ofbx::GeometryPartition::Polygon& polygon, int* triangulatedIndices)
|
||||||
|
{
|
||||||
|
if (polygon.vertex_count < 3)
|
||||||
|
return 0;
|
||||||
|
else if (polygon.vertex_count == 3)
|
||||||
|
{
|
||||||
|
triangulatedIndices[0] = polygon.from_vertex;
|
||||||
|
triangulatedIndices[1] = polygon.from_vertex + 1;
|
||||||
|
triangulatedIndices[2] = polygon.from_vertex + 2;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
else if (polygon.vertex_count == 4)
|
||||||
|
{
|
||||||
|
triangulatedIndices[0] = polygon.from_vertex + 0;
|
||||||
|
triangulatedIndices[1] = polygon.from_vertex + 1;
|
||||||
|
triangulatedIndices[2] = polygon.from_vertex + 2;
|
||||||
|
triangulatedIndices[3] = polygon.from_vertex + 0;
|
||||||
|
triangulatedIndices[4] = polygon.from_vertex + 2;
|
||||||
|
triangulatedIndices[5] = polygon.from_vertex + 3;
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ofbx::Vec3Attributes& positions = geom.getPositions();
|
||||||
|
Float3 normal = ToFloat3(geom.getNormals().get(polygon.from_vertex));
|
||||||
|
|
||||||
|
// Check if the polygon is convex
|
||||||
|
int lastSign = 0;
|
||||||
|
bool isConvex = true;
|
||||||
|
for (int i = 0; i < polygon.vertex_count; i++)
|
||||||
|
{
|
||||||
|
Float3 v1 = ToFloat3(positions.get(polygon.from_vertex + i));
|
||||||
|
Float3 v2 = ToFloat3(positions.get(polygon.from_vertex + (i + 1) % polygon.vertex_count));
|
||||||
|
Float3 v3 = ToFloat3(positions.get(polygon.from_vertex + (i + 2) % polygon.vertex_count));
|
||||||
|
|
||||||
|
// The winding order of all triangles must be same for polygon to be considered convex
|
||||||
|
int sign;
|
||||||
|
Float3 c = Float3::Cross(v1 - v2, v3 - v2);
|
||||||
|
if (c.LengthSquared() == 0.0f)
|
||||||
|
continue;
|
||||||
|
else if (Math::NotSameSign(c.X, normal.X) || Math::NotSameSign(c.Y, normal.Y) || Math::NotSameSign(c.Z, normal.Z))
|
||||||
|
sign = 1;
|
||||||
|
else
|
||||||
|
sign = -1;
|
||||||
|
if ((sign < 0 && lastSign > 0) || (sign > 0 && lastSign < 0))
|
||||||
|
{
|
||||||
|
isConvex = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lastSign += sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fast-path for convex case
|
||||||
|
if (isConvex)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < polygon.vertex_count - 2; i++)
|
||||||
|
{
|
||||||
|
triangulatedIndices[i * 3 + 0] = polygon.from_vertex;
|
||||||
|
triangulatedIndices[i * 3 + 1] = polygon.from_vertex + (i + 1) % polygon.vertex_count;
|
||||||
|
triangulatedIndices[i * 3 + 2] = polygon.from_vertex + (i + 2) % polygon.vertex_count;
|
||||||
|
}
|
||||||
|
return 3 * (polygon.vertex_count - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup arrays for temporary data (TODO: maybe double-linked list is more optimal?)
|
||||||
|
static Array<Float2> points;
|
||||||
|
static Array<int> indices;
|
||||||
|
static Array<int> earIndices;
|
||||||
|
points.Clear();
|
||||||
|
indices.Clear();
|
||||||
|
earIndices.Clear();
|
||||||
|
points.EnsureCapacity(polygon.vertex_count, false);
|
||||||
|
indices.EnsureCapacity(polygon.vertex_count, false);
|
||||||
|
earIndices.EnsureCapacity(3 * (polygon.vertex_count - 2), false);
|
||||||
|
|
||||||
|
// Project points to a plane, choose two arbitrary axises
|
||||||
|
const Float3 u = Float3::Cross(normal, Math::Abs(normal.X) > Math::Abs(normal.Y) ? Float3::Up : Float3::Right).GetNormalized();
|
||||||
|
const Float3 v = Float3::Cross(normal, u).GetNormalized();
|
||||||
|
for (int i = 0; i < polygon.vertex_count; i++)
|
||||||
|
{
|
||||||
|
const Float3 point = ToFloat3(positions.get(polygon.from_vertex + i));
|
||||||
|
const Float3 projectedPoint = Float3::ProjectOnPlane(point, normal);
|
||||||
|
const Float2 pointOnPlane = Float2(
|
||||||
|
projectedPoint.X * u.X + projectedPoint.Y * u.Y + projectedPoint.Z * u.Z,
|
||||||
|
projectedPoint.X * v.X + projectedPoint.Y * v.Y + projectedPoint.Z * v.Z);
|
||||||
|
|
||||||
|
points.Add(pointOnPlane);
|
||||||
|
indices.Add(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Triangulate non-convex polygons using simple ear-clipping algorithm (https://nils-olovsson.se/articles/ear_clipping_triangulation/)
|
||||||
|
const int maxIterations = indices.Count() * 10; // Safe guard to prevent infinite loop
|
||||||
|
int index = 0;
|
||||||
|
while (indices.Count() > 3 && index < maxIterations)
|
||||||
|
{
|
||||||
|
const int i1 = index % indices.Count();
|
||||||
|
const int i2 = (index + 1) % indices.Count();
|
||||||
|
const int i3 = (index + 2) % indices.Count();
|
||||||
|
const Float2 p1 = points[indices[i1]];
|
||||||
|
const Float2 p2 = points[indices[i2]];
|
||||||
|
const Float2 p3 = points[indices[i3]];
|
||||||
|
|
||||||
|
// TODO: Skip triangles with very sharp angles?
|
||||||
|
|
||||||
|
// Skip reflex vertices
|
||||||
|
if (Float2::Cross(p2 - p1, p3 - p1) < 0.0f)
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The triangle is considered to be an "ear" when no other points reside inside the triangle
|
||||||
|
bool isEar = true;
|
||||||
|
for (int j = 0; j < indices.Count(); j++)
|
||||||
|
{
|
||||||
|
if (j == i1 || j == i2 || j == i3)
|
||||||
|
continue;
|
||||||
|
const Float2 candidate = points[indices[j]];
|
||||||
|
if (CollisionsHelper::IsPointInTriangle(candidate, p1, p2, p3))
|
||||||
|
{
|
||||||
|
isEar = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isEar)
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add an ear and remove the tip point from evaluation
|
||||||
|
earIndices.Add(indices[i1]);
|
||||||
|
earIndices.Add(indices[i2]);
|
||||||
|
earIndices.Add(indices[i3]);
|
||||||
|
indices.RemoveAtKeepOrder(i2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < earIndices.Count(); i++)
|
||||||
|
triangulatedIndices[i] = polygon.from_vertex + (earIndices[i] % polygon.vertex_count);
|
||||||
|
triangulatedIndices[earIndices.Count() + 0] = polygon.from_vertex + (indices[0] % polygon.vertex_count);
|
||||||
|
triangulatedIndices[earIndices.Count() + 1] = polygon.from_vertex + (indices[1] % polygon.vertex_count);
|
||||||
|
triangulatedIndices[earIndices.Count() + 2] = polygon.from_vertex + (indices[2] % polygon.vertex_count);
|
||||||
|
|
||||||
|
return 3 * (polygon.vertex_count - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh* aMesh, MeshData& mesh, String& errorMsg, int partitionIndex)
|
||||||
{
|
{
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
mesh.Name = aMesh->name;
|
mesh.Name = aMesh->name;
|
||||||
ZoneText(*mesh.Name, mesh.Name.Length());
|
ZoneText(*mesh.Name, mesh.Name.Length());
|
||||||
const int32 firstVertexOffset = triangleStart * 3;
|
const ofbx::GeometryData& geometryData = aMesh->getGeometryData();
|
||||||
const int32 lastVertexOffset = triangleEnd * 3;
|
const ofbx::GeometryPartition& partition = geometryData.getPartition(partitionIndex);
|
||||||
const ofbx::Geometry* aGeometry = aMesh->getGeometry();
|
const int vertexCount = partition.triangles_count * 3;
|
||||||
const int vertexCount = lastVertexOffset - firstVertexOffset + 3;
|
const ofbx::Vec3Attributes& positions = geometryData.getPositions();
|
||||||
ASSERT(firstVertexOffset + vertexCount <= aGeometry->getVertexCount());
|
const ofbx::Vec2Attributes& uvs = geometryData.getUVs();
|
||||||
const ofbx::Vec3* vertices = aGeometry->getVertices();
|
const ofbx::Vec3Attributes& normals = geometryData.getNormals();
|
||||||
const ofbx::Vec3* normals = aGeometry->getNormals();
|
const ofbx::Vec3Attributes& tangents = geometryData.getTangents();
|
||||||
const ofbx::Vec3* tangents = aGeometry->getTangents();
|
const ofbx::Vec4Attributes& colors = geometryData.getColors();
|
||||||
const ofbx::Vec4* colors = aGeometry->getColors();
|
const ofbx::Skin* skin = aMesh->getSkin();
|
||||||
const ofbx::Vec2* uvs = aGeometry->getUVs();
|
const ofbx::BlendShape* blendShape = aMesh->getBlendShape();
|
||||||
const ofbx::Skin* skin = aGeometry->getSkin();
|
|
||||||
const ofbx::BlendShape* blendShape = aGeometry->getBlendShape();
|
static Array<int> triangulatedIndices;
|
||||||
|
triangulatedIndices.Resize(vertexCount, false);
|
||||||
|
static Array<Int4> blendIndices;
|
||||||
|
static Array<Float4> blendWeights;
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
const ofbx::Material* aMaterial = nullptr;
|
const ofbx::Material* aMaterial = nullptr;
|
||||||
if (aMesh->getMaterialCount() > 0)
|
if (aMesh->getMaterialCount() > 0)
|
||||||
{
|
aMaterial = aMesh->getMaterial(partitionIndex);
|
||||||
if (aGeometry->getMaterials())
|
|
||||||
aMaterial = aMesh->getMaterial(aGeometry->getMaterials()[triangleStart]);
|
|
||||||
else
|
|
||||||
aMaterial = aMesh->getMaterial(0);
|
|
||||||
}
|
|
||||||
mesh.MaterialSlotIndex = data.AddMaterial(result, aMaterial);
|
mesh.MaterialSlotIndex = data.AddMaterial(result, aMaterial);
|
||||||
|
|
||||||
// Vertex positions
|
// Vertex positions
|
||||||
mesh.Positions.Resize(vertexCount, false);
|
mesh.Positions.Resize(vertexCount, false);
|
||||||
for (int i = 0; i < vertexCount; i++)
|
{
|
||||||
mesh.Positions.Get()[i] = ToFloat3(vertices[i + firstVertexOffset]);
|
int numIndicesTotal = 0;
|
||||||
|
for (int i = 0; i < partition.polygon_count; i++)
|
||||||
|
{
|
||||||
|
int numIndices = Triangulate(geometryData, partition.polygons[i], &triangulatedIndices[numIndicesTotal]);
|
||||||
|
for (int j = numIndicesTotal; j < numIndicesTotal + numIndices; j++)
|
||||||
|
mesh.Positions.Get()[j] = ToFloat3(positions.get(triangulatedIndices[j]));
|
||||||
|
numIndicesTotal += numIndices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Indices (dummy index buffer)
|
// Indices (dummy index buffer)
|
||||||
if (vertexCount % 3 != 0)
|
|
||||||
{
|
|
||||||
errorMsg = TEXT("Invalid vertex count. It must be multiple of 3.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
mesh.Indices.Resize(vertexCount, false);
|
mesh.Indices.Resize(vertexCount, false);
|
||||||
for (int i = 0; i < vertexCount; i++)
|
for (int i = 0; i < vertexCount; i++)
|
||||||
mesh.Indices.Get()[i] = i;
|
mesh.Indices.Get()[i] = i;
|
||||||
|
|
||||||
// Texture coordinates
|
// Texture coordinates
|
||||||
if (uvs)
|
if (uvs.values)
|
||||||
{
|
{
|
||||||
mesh.UVs.Resize(vertexCount, false);
|
mesh.UVs.Resize(vertexCount, false);
|
||||||
for (int i = 0; i < vertexCount; i++)
|
for (int i = 0; i < vertexCount; i++)
|
||||||
mesh.UVs.Get()[i] = ToFloat2(uvs[i + firstVertexOffset]);
|
mesh.UVs.Get()[i] = ToFloat2(uvs.get(triangulatedIndices[i]));
|
||||||
if (data.ConvertRH)
|
if (data.ConvertRH)
|
||||||
{
|
{
|
||||||
for (int32 v = 0; v < vertexCount; v++)
|
for (int32 v = 0; v < vertexCount; v++)
|
||||||
@@ -582,7 +728,7 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Normals
|
// Normals
|
||||||
if (data.Options.CalculateNormals || !normals)
|
if (data.Options.CalculateNormals || !normals.values)
|
||||||
{
|
{
|
||||||
if (mesh.GenerateNormals(data.Options.SmoothingNormalsAngle))
|
if (mesh.GenerateNormals(data.Options.SmoothingNormalsAngle))
|
||||||
{
|
{
|
||||||
@@ -590,11 +736,11 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (normals)
|
else if (normals.values)
|
||||||
{
|
{
|
||||||
mesh.Normals.Resize(vertexCount, false);
|
mesh.Normals.Resize(vertexCount, false);
|
||||||
for (int i = 0; i < vertexCount; i++)
|
for (int i = 0; i < vertexCount; i++)
|
||||||
mesh.Normals.Get()[i] = ToFloat3(normals[i + firstVertexOffset]);
|
mesh.Normals.Get()[i] = ToFloat3(normals.get(triangulatedIndices[i]));
|
||||||
if (data.ConvertRH)
|
if (data.ConvertRH)
|
||||||
{
|
{
|
||||||
// Mirror normals along the Z axis
|
// Mirror normals along the Z axis
|
||||||
@@ -604,15 +750,15 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tangents
|
// Tangents
|
||||||
if ((data.Options.CalculateTangents || !tangents) && mesh.UVs.HasItems())
|
if ((data.Options.CalculateTangents || !tangents.values) && mesh.UVs.HasItems())
|
||||||
{
|
{
|
||||||
// Generated after full mesh data conversion
|
// Generated after full mesh data conversion
|
||||||
}
|
}
|
||||||
else if (tangents)
|
else if (tangents.values)
|
||||||
{
|
{
|
||||||
mesh.Tangents.Resize(vertexCount, false);
|
mesh.Tangents.Resize(vertexCount, false);
|
||||||
for (int i = 0; i < vertexCount; i++)
|
for (int i = 0; i < vertexCount; i++)
|
||||||
mesh.Tangents.Get()[i] = ToFloat3(tangents[i + firstVertexOffset]);
|
mesh.Tangents.Get()[i] = ToFloat3(tangents.get(triangulatedIndices[i]));
|
||||||
if (data.ConvertRH)
|
if (data.ConvertRH)
|
||||||
{
|
{
|
||||||
// Mirror tangents along the Z axis
|
// Mirror tangents along the Z axis
|
||||||
@@ -658,12 +804,12 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if has that channel texcoords
|
// Check if has that channel texcoords
|
||||||
const auto lightmapUVs = aGeometry->getUVs(inputChannelIndex);
|
const auto lightmapUVs = geometryData.getUVs(inputChannelIndex);
|
||||||
if (lightmapUVs)
|
if (lightmapUVs.values)
|
||||||
{
|
{
|
||||||
mesh.LightmapUVs.Resize(vertexCount, false);
|
mesh.LightmapUVs.Resize(vertexCount, false);
|
||||||
for (int i = 0; i < vertexCount; i++)
|
for (int i = 0; i < vertexCount; i++)
|
||||||
mesh.LightmapUVs.Get()[i] = ToFloat2(lightmapUVs[i + firstVertexOffset]);
|
mesh.LightmapUVs.Get()[i] = ToFloat2(lightmapUVs.get(triangulatedIndices[i]));
|
||||||
if (data.ConvertRH)
|
if (data.ConvertRH)
|
||||||
{
|
{
|
||||||
for (int32 v = 0; v < vertexCount; v++)
|
for (int32 v = 0; v < vertexCount; v++)
|
||||||
@@ -677,20 +823,20 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vertex Colors
|
// Vertex Colors
|
||||||
if (data.Options.ImportVertexColors && colors)
|
if (data.Options.ImportVertexColors && colors.values)
|
||||||
{
|
{
|
||||||
mesh.Colors.Resize(vertexCount, false);
|
mesh.Colors.Resize(vertexCount, false);
|
||||||
for (int i = 0; i < vertexCount; i++)
|
for (int i = 0; i < vertexCount; i++)
|
||||||
mesh.Colors.Get()[i] = ToColor(colors[i + firstVertexOffset]);
|
mesh.Colors.Get()[i] = ToColor(colors.get(triangulatedIndices[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blend Indices and Blend Weights
|
// Blend Indices and Blend Weights
|
||||||
if (skin && skin->getClusterCount() > 0 && EnumHasAnyFlags(data.Options.ImportTypes, ImportDataTypes::Skeleton))
|
if (skin && skin->getClusterCount() > 0 && EnumHasAnyFlags(data.Options.ImportTypes, ImportDataTypes::Skeleton))
|
||||||
{
|
{
|
||||||
mesh.BlendIndices.Resize(vertexCount);
|
blendIndices.Resize(positions.values_count, false);
|
||||||
mesh.BlendWeights.Resize(vertexCount);
|
blendWeights.Resize(positions.values_count, false);
|
||||||
mesh.BlendIndices.SetAll(Int4::Zero);
|
blendIndices.SetAll(Int4::Zero);
|
||||||
mesh.BlendWeights.SetAll(Float4::Zero);
|
blendWeights.SetAll(Float4::Zero);
|
||||||
|
|
||||||
for (int clusterIndex = 0, clusterCount = skin->getClusterCount(); clusterIndex < clusterCount; clusterIndex++)
|
for (int clusterIndex = 0, clusterCount = skin->getClusterCount(); clusterIndex < clusterCount; clusterIndex++)
|
||||||
{
|
{
|
||||||
@@ -718,12 +864,12 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
const double* clusterWeights = cluster->getWeights();
|
const double* clusterWeights = cluster->getWeights();
|
||||||
for (int j = 0; j < cluster->getIndicesCount(); j++)
|
for (int j = 0; j < cluster->getIndicesCount(); j++)
|
||||||
{
|
{
|
||||||
int vtxIndex = clusterIndices[j] - firstVertexOffset;
|
int vtxIndex = clusterIndices[j];
|
||||||
float vtxWeight = (float)clusterWeights[j];
|
float vtxWeight = (float)clusterWeights[j];
|
||||||
if (vtxWeight <= 0 || vtxIndex < 0 || vtxIndex >= vertexCount)
|
if (vtxWeight <= 0 || vtxIndex < 0 || vtxIndex >= vertexCount)
|
||||||
continue;
|
continue;
|
||||||
Int4& indices = mesh.BlendIndices.Get()[vtxIndex];
|
Int4& indices = blendIndices.Get()[vtxIndex];
|
||||||
Float4& weights = mesh.BlendWeights.Get()[vtxIndex];
|
Float4& weights = blendWeights.Get()[vtxIndex];
|
||||||
|
|
||||||
for (int32 k = 0; k < 4; k++)
|
for (int32 k = 0; k < 4; k++)
|
||||||
{
|
{
|
||||||
@@ -745,6 +891,15 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remap blend values to triangulated data
|
||||||
|
mesh.BlendIndices.Resize(vertexCount, false);
|
||||||
|
mesh.BlendWeights.Resize(vertexCount, false);
|
||||||
|
for (int i = 0; i < triangulatedIndices.Count(); i++)
|
||||||
|
{
|
||||||
|
mesh.BlendIndices.Get()[i] = blendIndices[positions.indices[triangulatedIndices[i]]];
|
||||||
|
mesh.BlendWeights.Get()[i] = blendWeights[positions.indices[triangulatedIndices[i]]];
|
||||||
|
}
|
||||||
|
|
||||||
mesh.NormalizeBlendWeights();
|
mesh.NormalizeBlendWeights();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,9 +917,9 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
continue;
|
continue;
|
||||||
const ofbx::Shape* shape = channel->getShape(targetShapeCount - 1);
|
const ofbx::Shape* shape = channel->getShape(targetShapeCount - 1);
|
||||||
|
|
||||||
if (shape->getVertexCount() != aGeometry->getVertexCount())
|
if (shape->getVertexCount() != vertexCount)
|
||||||
{
|
{
|
||||||
LOG(Error, "Blend shape '{0}' in mesh '{1}' has different amount of vertices ({2}) than mesh ({3})", String(shape->name), mesh.Name, shape->getVertexCount(), aGeometry->getVertexCount());
|
LOG(Error, "Blend shape '{0}' in mesh '{1}' has different amount of vertices ({2}) than mesh ({3})", String(shape->name), mesh.Name, shape->getVertexCount(), vertexCount);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -779,14 +934,14 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
auto shapeVertices = shape->getVertices();
|
auto shapeVertices = shape->getVertices();
|
||||||
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
||||||
{
|
{
|
||||||
auto delta = ToFloat3(shapeVertices[i + firstVertexOffset]) - mesh.Positions.Get()[i];
|
auto delta = ToFloat3(shapeVertices[i]) - mesh.Positions.Get()[i];
|
||||||
blendShapeData.Vertices.Get()[i].PositionDelta = delta;
|
blendShapeData.Vertices.Get()[i].PositionDelta = delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto shapeNormals = shape->getNormals();
|
auto shapeNormals = shape->getNormals();
|
||||||
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
||||||
{
|
{
|
||||||
auto delta = ToFloat3(shapeNormals[i + firstVertexOffset]);
|
auto delta = ToFloat3(shapeNormals[i]);
|
||||||
if (data.ConvertRH)
|
if (data.ConvertRH)
|
||||||
{
|
{
|
||||||
// Mirror normals along the Z axis
|
// Mirror normals along the Z axis
|
||||||
@@ -820,7 +975,7 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
Swap(mesh.Indices.Get()[i], mesh.Indices.Get()[i + 2]);
|
Swap(mesh.Indices.Get()[i], mesh.Indices.Get()[i + 2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((data.Options.CalculateTangents || !tangents) && mesh.UVs.HasItems())
|
if ((data.Options.CalculateTangents || !tangents.values) && mesh.UVs.HasItems())
|
||||||
{
|
{
|
||||||
if (mesh.GenerateTangents(data.Options.SmoothingTangentsAngle))
|
if (mesh.GenerateTangents(data.Options.SmoothingTangentsAngle))
|
||||||
{
|
{
|
||||||
@@ -858,7 +1013,7 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImportMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh* aMesh, String& errorMsg, int32 triangleStart, int32 triangleEnd)
|
bool ImportMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh* aMesh, String& errorMsg, int partitionIndex)
|
||||||
{
|
{
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
|
|
||||||
@@ -899,7 +1054,7 @@ bool ImportMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
|
|
||||||
// Import mesh data
|
// Import mesh data
|
||||||
MeshData* meshData = New<MeshData>();
|
MeshData* meshData = New<MeshData>();
|
||||||
if (ProcessMesh(result, data, aMesh, *meshData, errorMsg, triangleStart, triangleEnd))
|
if (ProcessMesh(result, data, aMesh, *meshData, errorMsg, partitionIndex))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Link mesh
|
// Link mesh
|
||||||
@@ -916,36 +1071,17 @@ bool ImportMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
|
|||||||
bool ImportMesh(int32 index, ModelData& result, OpenFbxImporterData& data, String& errorMsg)
|
bool ImportMesh(int32 index, ModelData& result, OpenFbxImporterData& data, String& errorMsg)
|
||||||
{
|
{
|
||||||
const auto aMesh = data.Scene->getMesh(index);
|
const auto aMesh = data.Scene->getMesh(index);
|
||||||
const auto aGeometry = aMesh->getGeometry();
|
|
||||||
const auto trianglesCount = aGeometry->getVertexCount() / 3;
|
|
||||||
if (IsMeshInvalid(aMesh))
|
if (IsMeshInvalid(aMesh))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (aMesh->getMaterialCount() < 2 || !aGeometry->getMaterials())
|
const auto& geomData = aMesh->getGeometryData();
|
||||||
|
for (int i = 0; i < geomData.getPartitionCount(); i++)
|
||||||
{
|
{
|
||||||
// Fast path if mesh is using single material for all triangles
|
const auto& partition = geomData.getPartition(i);
|
||||||
if (ImportMesh(result, data, aMesh, errorMsg, 0, trianglesCount - 1))
|
if (partition.polygon_count == 0)
|
||||||
return true;
|
continue;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Create mesh for each sequence of triangles that share the same material
|
|
||||||
const auto materials = aGeometry->getMaterials();
|
|
||||||
int32 rangeStart = 0;
|
|
||||||
int32 rangeStartVal = materials[rangeStart];
|
|
||||||
for (int32 triangleIndex = 1; triangleIndex < trianglesCount; triangleIndex++)
|
|
||||||
{
|
|
||||||
if (rangeStartVal != materials[triangleIndex])
|
|
||||||
{
|
|
||||||
if (ImportMesh(result, data, aMesh, errorMsg, rangeStart, triangleIndex - 1))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Start a new range
|
if (ImportMesh(result, data, aMesh, errorMsg, i))
|
||||||
rangeStart = triangleIndex;
|
|
||||||
rangeStartVal = materials[triangleIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ImportMesh(result, data, aMesh, errorMsg, rangeStart, trianglesCount - 1))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -962,35 +1098,35 @@ struct AnimInfo
|
|||||||
|
|
||||||
struct Frame
|
struct Frame
|
||||||
{
|
{
|
||||||
ofbx::Vec3 Translation;
|
ofbx::DVec3 Translation;
|
||||||
ofbx::Vec3 Rotation;
|
ofbx::DVec3 Rotation;
|
||||||
ofbx::Vec3 Scaling;
|
ofbx::DVec3 Scaling;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ExtractKeyframePosition(const ofbx::Object* bone, ofbx::Vec3& trans, const Frame& localFrame, Float3& keyframe)
|
void ExtractKeyframePosition(const ofbx::Object* bone, ofbx::DVec3& trans, const Frame& localFrame, Float3& keyframe)
|
||||||
{
|
{
|
||||||
const Matrix frameTrans = ToMatrix(bone->evalLocal(trans, localFrame.Rotation, localFrame.Scaling));
|
const Matrix frameTrans = ToMatrix(bone->evalLocal(trans, localFrame.Rotation, localFrame.Scaling));
|
||||||
keyframe = frameTrans.GetTranslation();
|
keyframe = frameTrans.GetTranslation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractKeyframeRotation(const ofbx::Object* bone, ofbx::Vec3& trans, const Frame& localFrame, Quaternion& keyframe)
|
void ExtractKeyframeRotation(const ofbx::Object* bone, ofbx::DVec3& trans, const Frame& localFrame, Quaternion& keyframe)
|
||||||
{
|
{
|
||||||
const Matrix frameTrans = ToMatrix(bone->evalLocal(localFrame.Translation, trans, { 1.0, 1.0, 1.0 }));
|
const Matrix frameTrans = ToMatrix(bone->evalLocal(localFrame.Translation, trans, { 1.0, 1.0, 1.0 }));
|
||||||
Quaternion::RotationMatrix(frameTrans, keyframe);
|
Quaternion::RotationMatrix(frameTrans, keyframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractKeyframeScale(const ofbx::Object* bone, ofbx::Vec3& trans, const Frame& localFrame, Float3& keyframe)
|
void ExtractKeyframeScale(const ofbx::Object* bone, ofbx::DVec3& trans, const Frame& localFrame, Float3& keyframe)
|
||||||
{
|
{
|
||||||
// Fix empty scale case
|
// Fix empty scale case
|
||||||
if (Math::IsZero(trans.x) && Math::IsZero(trans.y) && Math::IsZero(trans.z))
|
if (Math::IsZero(trans.x) && Math::IsZero(trans.y) && Math::IsZero(trans.z))
|
||||||
trans = { 1.0, 1.0, 1.0 };
|
trans = { 1.0, 1.0, 1.0 };
|
||||||
|
|
||||||
const Matrix frameTrans = ToMatrix(bone->evalLocal(localFrame.Translation, localFrame.Rotation, trans));
|
const Matrix frameTrans = ToMatrix(bone->evalLocal(localFrame.Translation, { 0.0, 0.0, 0.0 }, trans));
|
||||||
keyframe = frameTrans.GetScaleVector();
|
keyframe = frameTrans.GetScaleVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void ImportCurve(const ofbx::AnimationCurveNode* curveNode, LinearCurve<T>& curve, AnimInfo& info, void (*ExtractKeyframe)(const ofbx::Object*, ofbx::Vec3&, const Frame&, T&))
|
void ImportCurve(const ofbx::AnimationCurveNode* curveNode, LinearCurve<T>& curve, AnimInfo& info, void (*ExtractKeyframe)(const ofbx::Object*, ofbx::DVec3&, const Frame&, T&))
|
||||||
{
|
{
|
||||||
if (curveNode == nullptr)
|
if (curveNode == nullptr)
|
||||||
return;
|
return;
|
||||||
@@ -1008,7 +1144,7 @@ void ImportCurve(const ofbx::AnimationCurveNode* curveNode, LinearCurve<T>& curv
|
|||||||
|
|
||||||
key.Time = (float)i;
|
key.Time = (float)i;
|
||||||
|
|
||||||
ofbx::Vec3 trans = curveNode->getNodeLocalTransform(t);
|
ofbx::DVec3 trans = curveNode->getNodeLocalTransform(t);
|
||||||
ExtractKeyframe(bone, trans, localFrame, key.Value);
|
ExtractKeyframe(bone, trans, localFrame, key.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1125,10 +1261,9 @@ bool ModelTool::ImportDataOpenFBX(const String& path, ModelData& data, Options&
|
|||||||
errorMsg = TEXT("Cannot load file.");
|
errorMsg = TEXT("Cannot load file.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ofbx::u64 loadFlags = 0;
|
ofbx::u16 loadFlags = 0;
|
||||||
if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Geometry))
|
if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Geometry))
|
||||||
{
|
{
|
||||||
loadFlags |= (ofbx::u64)ofbx::LoadFlags::TRIANGULATE;
|
|
||||||
if (!options.ImportBlendShapes)
|
if (!options.ImportBlendShapes)
|
||||||
loadFlags |= (ofbx::u64)ofbx::LoadFlags::IGNORE_BLEND_SHAPES;
|
loadFlags |= (ofbx::u64)ofbx::LoadFlags::IGNORE_BLEND_SHAPES;
|
||||||
}
|
}
|
||||||
|
|||||||
4193
Source/ThirdParty/OpenFBX/libdeflate.cpp
vendored
Normal file
4193
Source/ThirdParty/OpenFBX/libdeflate.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
411
Source/ThirdParty/OpenFBX/libdeflate.h
vendored
Normal file
411
Source/ThirdParty/OpenFBX/libdeflate.h
vendored
Normal file
@@ -0,0 +1,411 @@
|
|||||||
|
/*
|
||||||
|
* libdeflate.h - public header for libdeflate
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBDEFLATE_H
|
||||||
|
#define LIBDEFLATE_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIBDEFLATE_VERSION_MAJOR 1
|
||||||
|
#define LIBDEFLATE_VERSION_MINOR 18
|
||||||
|
#define LIBDEFLATE_VERSION_STRING "1.18"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Users of libdeflate.dll on Windows can define LIBDEFLATE_DLL to cause
|
||||||
|
* __declspec(dllimport) to be used. This should be done when it's easy to do.
|
||||||
|
* Otherwise it's fine to skip it, since it is a very minor performance
|
||||||
|
* optimization that is irrelevant for most use cases of libdeflate.
|
||||||
|
*/
|
||||||
|
#ifndef LIBDEFLATEAPI
|
||||||
|
# if defined(LIBDEFLATE_DLL) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||||
|
# define LIBDEFLATEAPI __declspec(dllimport)
|
||||||
|
# else
|
||||||
|
# define LIBDEFLATEAPI
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ========================================================================== */
|
||||||
|
/* Compression */
|
||||||
|
/* ========================================================================== */
|
||||||
|
|
||||||
|
struct libdeflate_compressor;
|
||||||
|
struct libdeflate_options;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libdeflate_alloc_compressor() allocates a new compressor that supports
|
||||||
|
* DEFLATE, zlib, and gzip compression. 'compression_level' is the compression
|
||||||
|
* level on a zlib-like scale but with a higher maximum value (1 = fastest, 6 =
|
||||||
|
* medium/default, 9 = slow, 12 = slowest). Level 0 is also supported and means
|
||||||
|
* "no compression", specifically "create a valid stream, but only emit
|
||||||
|
* uncompressed blocks" (this will expand the data slightly).
|
||||||
|
*
|
||||||
|
* The return value is a pointer to the new compressor, or NULL if out of memory
|
||||||
|
* or if the compression level is invalid (i.e. outside the range [0, 12]).
|
||||||
|
*
|
||||||
|
* Note: for compression, the sliding window size is defined at compilation time
|
||||||
|
* to 32768, the largest size permissible in the DEFLATE format. It cannot be
|
||||||
|
* changed at runtime.
|
||||||
|
*
|
||||||
|
* A single compressor is not safe to use by multiple threads concurrently.
|
||||||
|
* However, different threads may use different compressors concurrently.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI struct libdeflate_compressor *
|
||||||
|
libdeflate_alloc_compressor(int compression_level);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_alloc_compressor(), but adds the 'options' argument.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI struct libdeflate_compressor *
|
||||||
|
libdeflate_alloc_compressor_ex(int compression_level,
|
||||||
|
const struct libdeflate_options *options);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libdeflate_deflate_compress() performs raw DEFLATE compression on a buffer of
|
||||||
|
* data. It attempts to compress 'in_nbytes' bytes of data located at 'in' and
|
||||||
|
* write the result to 'out', which has space for 'out_nbytes_avail' bytes. The
|
||||||
|
* return value is the compressed size in bytes, or 0 if the data could not be
|
||||||
|
* compressed to 'out_nbytes_avail' bytes or fewer (but see note below).
|
||||||
|
*
|
||||||
|
* If compression is successful, then the output data is guaranteed to be a
|
||||||
|
* valid DEFLATE stream that decompresses to the input data. No other
|
||||||
|
* guarantees are made about the output data. Notably, different versions of
|
||||||
|
* libdeflate can produce different compressed data for the same uncompressed
|
||||||
|
* data, even at the same compression level. Do ***NOT*** do things like
|
||||||
|
* writing tests that compare compressed data to a golden output, as this can
|
||||||
|
* break when libdeflate is updated. (This property isn't specific to
|
||||||
|
* libdeflate; the same is true for zlib and other compression libraries too.)
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI size_t
|
||||||
|
libdeflate_deflate_compress(struct libdeflate_compressor *compressor,
|
||||||
|
const void *in, size_t in_nbytes,
|
||||||
|
void *out, size_t out_nbytes_avail);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libdeflate_deflate_compress_bound() returns a worst-case upper bound on the
|
||||||
|
* number of bytes of compressed data that may be produced by compressing any
|
||||||
|
* buffer of length less than or equal to 'in_nbytes' using
|
||||||
|
* libdeflate_deflate_compress() with the specified compressor. This bound will
|
||||||
|
* necessarily be a number greater than or equal to 'in_nbytes'. It may be an
|
||||||
|
* overestimate of the true upper bound. The return value is guaranteed to be
|
||||||
|
* the same for all invocations with the same compressor and same 'in_nbytes'.
|
||||||
|
*
|
||||||
|
* As a special case, 'compressor' may be NULL. This causes the bound to be
|
||||||
|
* taken across *any* libdeflate_compressor that could ever be allocated with
|
||||||
|
* this build of the library, with any options.
|
||||||
|
*
|
||||||
|
* Note that this function is not necessary in many applications. With
|
||||||
|
* block-based compression, it is usually preferable to separately store the
|
||||||
|
* uncompressed size of each block and to store any blocks that did not compress
|
||||||
|
* to less than their original size uncompressed. In that scenario, there is no
|
||||||
|
* need to know the worst-case compressed size, since the maximum number of
|
||||||
|
* bytes of compressed data that may be used would always be one less than the
|
||||||
|
* input length. You can just pass a buffer of that size to
|
||||||
|
* libdeflate_deflate_compress() and store the data uncompressed if
|
||||||
|
* libdeflate_deflate_compress() returns 0, indicating that the compressed data
|
||||||
|
* did not fit into the provided output buffer.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI size_t
|
||||||
|
libdeflate_deflate_compress_bound(struct libdeflate_compressor *compressor,
|
||||||
|
size_t in_nbytes);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_deflate_compress(), but uses the zlib wrapper format instead
|
||||||
|
* of raw DEFLATE.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI size_t
|
||||||
|
libdeflate_zlib_compress(struct libdeflate_compressor *compressor,
|
||||||
|
const void *in, size_t in_nbytes,
|
||||||
|
void *out, size_t out_nbytes_avail);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_deflate_compress_bound(), but assumes the data will be
|
||||||
|
* compressed with libdeflate_zlib_compress() rather than with
|
||||||
|
* libdeflate_deflate_compress().
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI size_t
|
||||||
|
libdeflate_zlib_compress_bound(struct libdeflate_compressor *compressor,
|
||||||
|
size_t in_nbytes);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_deflate_compress(), but uses the gzip wrapper format instead
|
||||||
|
* of raw DEFLATE.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI size_t
|
||||||
|
libdeflate_gzip_compress(struct libdeflate_compressor *compressor,
|
||||||
|
const void *in, size_t in_nbytes,
|
||||||
|
void *out, size_t out_nbytes_avail);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_deflate_compress_bound(), but assumes the data will be
|
||||||
|
* compressed with libdeflate_gzip_compress() rather than with
|
||||||
|
* libdeflate_deflate_compress().
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI size_t
|
||||||
|
libdeflate_gzip_compress_bound(struct libdeflate_compressor *compressor,
|
||||||
|
size_t in_nbytes);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libdeflate_free_compressor() frees a compressor that was allocated with
|
||||||
|
* libdeflate_alloc_compressor(). If a NULL pointer is passed in, no action is
|
||||||
|
* taken.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI void
|
||||||
|
libdeflate_free_compressor(struct libdeflate_compressor *compressor);
|
||||||
|
|
||||||
|
/* ========================================================================== */
|
||||||
|
/* Decompression */
|
||||||
|
/* ========================================================================== */
|
||||||
|
|
||||||
|
struct libdeflate_decompressor;
|
||||||
|
struct libdeflate_options;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libdeflate_alloc_decompressor() allocates a new decompressor that can be used
|
||||||
|
* for DEFLATE, zlib, and gzip decompression. The return value is a pointer to
|
||||||
|
* the new decompressor, or NULL if out of memory.
|
||||||
|
*
|
||||||
|
* This function takes no parameters, and the returned decompressor is valid for
|
||||||
|
* decompressing data that was compressed at any compression level and with any
|
||||||
|
* sliding window size.
|
||||||
|
*
|
||||||
|
* A single decompressor is not safe to use by multiple threads concurrently.
|
||||||
|
* However, different threads may use different decompressors concurrently.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI struct libdeflate_decompressor *
|
||||||
|
libdeflate_alloc_decompressor(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_alloc_decompressor(), but adds the 'options' argument.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI struct libdeflate_decompressor *
|
||||||
|
libdeflate_alloc_decompressor_ex(const struct libdeflate_options *options);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Result of a call to libdeflate_deflate_decompress(),
|
||||||
|
* libdeflate_zlib_decompress(), or libdeflate_gzip_decompress().
|
||||||
|
*/
|
||||||
|
enum libdeflate_result {
|
||||||
|
/* Decompression was successful. */
|
||||||
|
LIBDEFLATE_SUCCESS = 0,
|
||||||
|
|
||||||
|
/* Decompression failed because the compressed data was invalid,
|
||||||
|
* corrupt, or otherwise unsupported. */
|
||||||
|
LIBDEFLATE_BAD_DATA = 1,
|
||||||
|
|
||||||
|
/* A NULL 'actual_out_nbytes_ret' was provided, but the data would have
|
||||||
|
* decompressed to fewer than 'out_nbytes_avail' bytes. */
|
||||||
|
LIBDEFLATE_SHORT_OUTPUT = 2,
|
||||||
|
|
||||||
|
/* The data would have decompressed to more than 'out_nbytes_avail'
|
||||||
|
* bytes. */
|
||||||
|
LIBDEFLATE_INSUFFICIENT_SPACE = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libdeflate_deflate_decompress() decompresses a DEFLATE stream from the buffer
|
||||||
|
* 'in' with compressed size up to 'in_nbytes' bytes. The uncompressed data is
|
||||||
|
* written to 'out', a buffer with size 'out_nbytes_avail' bytes. If
|
||||||
|
* decompression succeeds, then 0 (LIBDEFLATE_SUCCESS) is returned. Otherwise,
|
||||||
|
* a nonzero result code such as LIBDEFLATE_BAD_DATA is returned, and the
|
||||||
|
* contents of the output buffer are undefined.
|
||||||
|
*
|
||||||
|
* Decompression stops at the end of the DEFLATE stream (as indicated by the
|
||||||
|
* BFINAL flag), even if it is actually shorter than 'in_nbytes' bytes.
|
||||||
|
*
|
||||||
|
* libdeflate_deflate_decompress() can be used in cases where the actual
|
||||||
|
* uncompressed size is known (recommended) or unknown (not recommended):
|
||||||
|
*
|
||||||
|
* - If the actual uncompressed size is known, then pass the actual
|
||||||
|
* uncompressed size as 'out_nbytes_avail' and pass NULL for
|
||||||
|
* 'actual_out_nbytes_ret'. This makes libdeflate_deflate_decompress() fail
|
||||||
|
* with LIBDEFLATE_SHORT_OUTPUT if the data decompressed to fewer than the
|
||||||
|
* specified number of bytes.
|
||||||
|
*
|
||||||
|
* - If the actual uncompressed size is unknown, then provide a non-NULL
|
||||||
|
* 'actual_out_nbytes_ret' and provide a buffer with some size
|
||||||
|
* 'out_nbytes_avail' that you think is large enough to hold all the
|
||||||
|
* uncompressed data. In this case, if the data decompresses to less than
|
||||||
|
* or equal to 'out_nbytes_avail' bytes, then
|
||||||
|
* libdeflate_deflate_decompress() will write the actual uncompressed size
|
||||||
|
* to *actual_out_nbytes_ret and return 0 (LIBDEFLATE_SUCCESS). Otherwise,
|
||||||
|
* it will return LIBDEFLATE_INSUFFICIENT_SPACE if the provided buffer was
|
||||||
|
* not large enough but no other problems were encountered, or another
|
||||||
|
* nonzero result code if decompression failed for another reason.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI enum libdeflate_result
|
||||||
|
libdeflate_deflate_decompress(struct libdeflate_decompressor *decompressor,
|
||||||
|
const void *in, size_t in_nbytes,
|
||||||
|
void *out, size_t out_nbytes_avail,
|
||||||
|
size_t *actual_out_nbytes_ret);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_deflate_decompress(), but adds the 'actual_in_nbytes_ret'
|
||||||
|
* argument. If decompression succeeds and 'actual_in_nbytes_ret' is not NULL,
|
||||||
|
* then the actual compressed size of the DEFLATE stream (aligned to the next
|
||||||
|
* byte boundary) is written to *actual_in_nbytes_ret.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI enum libdeflate_result
|
||||||
|
libdeflate_deflate_decompress_ex(struct libdeflate_decompressor *decompressor,
|
||||||
|
const void *in, size_t in_nbytes,
|
||||||
|
void *out, size_t out_nbytes_avail,
|
||||||
|
size_t *actual_in_nbytes_ret,
|
||||||
|
size_t *actual_out_nbytes_ret);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_deflate_decompress(), but assumes the zlib wrapper format
|
||||||
|
* instead of raw DEFLATE.
|
||||||
|
*
|
||||||
|
* Decompression will stop at the end of the zlib stream, even if it is shorter
|
||||||
|
* than 'in_nbytes'. If you need to know exactly where the zlib stream ended,
|
||||||
|
* use libdeflate_zlib_decompress_ex().
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI enum libdeflate_result
|
||||||
|
libdeflate_zlib_decompress(struct libdeflate_decompressor *decompressor,
|
||||||
|
const void *in, size_t in_nbytes,
|
||||||
|
void *out, size_t out_nbytes_avail,
|
||||||
|
size_t *actual_out_nbytes_ret);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_zlib_decompress(), but adds the 'actual_in_nbytes_ret'
|
||||||
|
* argument. If 'actual_in_nbytes_ret' is not NULL and the decompression
|
||||||
|
* succeeds (indicating that the first zlib-compressed stream in the input
|
||||||
|
* buffer was decompressed), then the actual number of input bytes consumed is
|
||||||
|
* written to *actual_in_nbytes_ret.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI enum libdeflate_result
|
||||||
|
libdeflate_zlib_decompress_ex(struct libdeflate_decompressor *decompressor,
|
||||||
|
const void *in, size_t in_nbytes,
|
||||||
|
void *out, size_t out_nbytes_avail,
|
||||||
|
size_t *actual_in_nbytes_ret,
|
||||||
|
size_t *actual_out_nbytes_ret);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_deflate_decompress(), but assumes the gzip wrapper format
|
||||||
|
* instead of raw DEFLATE.
|
||||||
|
*
|
||||||
|
* If multiple gzip-compressed members are concatenated, then only the first
|
||||||
|
* will be decompressed. Use libdeflate_gzip_decompress_ex() if you need
|
||||||
|
* multi-member support.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI enum libdeflate_result
|
||||||
|
libdeflate_gzip_decompress(struct libdeflate_decompressor *decompressor,
|
||||||
|
const void *in, size_t in_nbytes,
|
||||||
|
void *out, size_t out_nbytes_avail,
|
||||||
|
size_t *actual_out_nbytes_ret);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like libdeflate_gzip_decompress(), but adds the 'actual_in_nbytes_ret'
|
||||||
|
* argument. If 'actual_in_nbytes_ret' is not NULL and the decompression
|
||||||
|
* succeeds (indicating that the first gzip-compressed member in the input
|
||||||
|
* buffer was decompressed), then the actual number of input bytes consumed is
|
||||||
|
* written to *actual_in_nbytes_ret.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI enum libdeflate_result
|
||||||
|
libdeflate_gzip_decompress_ex(struct libdeflate_decompressor *decompressor,
|
||||||
|
const void *in, size_t in_nbytes,
|
||||||
|
void *out, size_t out_nbytes_avail,
|
||||||
|
size_t *actual_in_nbytes_ret,
|
||||||
|
size_t *actual_out_nbytes_ret);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libdeflate_free_decompressor() frees a decompressor that was allocated with
|
||||||
|
* libdeflate_alloc_decompressor(). If a NULL pointer is passed in, no action
|
||||||
|
* is taken.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI void
|
||||||
|
libdeflate_free_decompressor(struct libdeflate_decompressor *decompressor);
|
||||||
|
|
||||||
|
/* ========================================================================== */
|
||||||
|
/* Checksums */
|
||||||
|
/* ========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libdeflate_adler32() updates a running Adler-32 checksum with 'len' bytes of
|
||||||
|
* data and returns the updated checksum. When starting a new checksum, the
|
||||||
|
* required initial value for 'adler' is 1. This value is also returned when
|
||||||
|
* 'buffer' is specified as NULL.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI uint32_t
|
||||||
|
libdeflate_adler32(uint32_t adler, const void *buffer, size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libdeflate_crc32() updates a running CRC-32 checksum with 'len' bytes of data
|
||||||
|
* and returns the updated checksum. When starting a new checksum, the required
|
||||||
|
* initial value for 'crc' is 0. This value is also returned when 'buffer' is
|
||||||
|
* specified as NULL.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI uint32_t
|
||||||
|
libdeflate_crc32(uint32_t crc, const void *buffer, size_t len);
|
||||||
|
|
||||||
|
/* ========================================================================== */
|
||||||
|
/* Custom memory allocator */
|
||||||
|
/* ========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Install a custom memory allocator which libdeflate will use for all memory
|
||||||
|
* allocations by default. 'malloc_func' is a function that must behave like
|
||||||
|
* malloc(), and 'free_func' is a function that must behave like free().
|
||||||
|
*
|
||||||
|
* The per-(de)compressor custom memory allocator that can be specified in
|
||||||
|
* 'struct libdeflate_options' takes priority over this.
|
||||||
|
*
|
||||||
|
* This doesn't affect the free() function that will be used to free
|
||||||
|
* (de)compressors that were already in existence when this is called.
|
||||||
|
*/
|
||||||
|
LIBDEFLATEAPI void
|
||||||
|
libdeflate_set_memory_allocator(void *(*malloc_func)(size_t),
|
||||||
|
void (*free_func)(void *));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Advanced options. This is the options structure that
|
||||||
|
* libdeflate_alloc_compressor_ex() and libdeflate_alloc_decompressor_ex()
|
||||||
|
* require. Most users won't need this and should just use the non-"_ex"
|
||||||
|
* functions instead. If you do need this, it should be initialized like this:
|
||||||
|
*
|
||||||
|
* struct libdeflate_options options;
|
||||||
|
*
|
||||||
|
* memset(&options, 0, sizeof(options));
|
||||||
|
* options.sizeof_options = sizeof(options);
|
||||||
|
* // Then set the fields that you need to override the defaults for.
|
||||||
|
*/
|
||||||
|
struct libdeflate_options {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This field must be set to the struct size. This field exists for
|
||||||
|
* extensibility, so that fields can be appended to this struct in
|
||||||
|
* future versions of libdeflate while still supporting old binaries.
|
||||||
|
*/
|
||||||
|
size_t sizeof_options;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An optional custom memory allocator to use for this (de)compressor.
|
||||||
|
* 'malloc_func' must be a function that behaves like malloc(), and
|
||||||
|
* 'free_func' must be a function that behaves like free().
|
||||||
|
*
|
||||||
|
* This is useful in cases where a process might have multiple users of
|
||||||
|
* libdeflate who want to use different memory allocators. For example,
|
||||||
|
* a library might want to use libdeflate with a custom memory allocator
|
||||||
|
* without interfering with user code that might use libdeflate too.
|
||||||
|
*
|
||||||
|
* This takes priority over the "global" memory allocator (which by
|
||||||
|
* default is malloc() and free(), but can be changed by
|
||||||
|
* libdeflate_set_memory_allocator()). Moreover, libdeflate will never
|
||||||
|
* call the "global" memory allocator if a per-(de)compressor custom
|
||||||
|
* allocator is always given.
|
||||||
|
*/
|
||||||
|
void *(*malloc_func)(size_t);
|
||||||
|
void (*free_func)(void *);
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LIBDEFLATE_H */
|
||||||
2951
Source/ThirdParty/OpenFBX/ofbx.cpp
vendored
2951
Source/ThirdParty/OpenFBX/ofbx.cpp
vendored
File diff suppressed because it is too large
Load Diff
425
Source/ThirdParty/OpenFBX/ofbx.h
vendored
425
Source/ThirdParty/OpenFBX/ofbx.h
vendored
@@ -9,10 +9,10 @@ typedef unsigned char u8;
|
|||||||
typedef unsigned short u16;
|
typedef unsigned short u16;
|
||||||
typedef unsigned int u32;
|
typedef unsigned int u32;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
typedef long long i64;
|
typedef long long i64;
|
||||||
typedef unsigned long long u64;
|
typedef unsigned long long u64;
|
||||||
#else
|
#else
|
||||||
typedef long i64;
|
typedef long i64;
|
||||||
typedef unsigned long u64;
|
typedef unsigned long u64;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -21,46 +21,71 @@ static_assert(sizeof(u32) == 4, "u32 is not 4 bytes");
|
|||||||
static_assert(sizeof(u64) == 8, "u64 is not 8 bytes");
|
static_assert(sizeof(u64) == 8, "u64 is not 8 bytes");
|
||||||
static_assert(sizeof(i64) == 8, "i64 is not 8 bytes");
|
static_assert(sizeof(i64) == 8, "i64 is not 8 bytes");
|
||||||
|
|
||||||
|
typedef decltype(sizeof(0)) usize;
|
||||||
|
|
||||||
using JobFunction = void (*)(void*);
|
using JobFunction = void (*)(void*);
|
||||||
using JobProcessor = void (*)(JobFunction, void*, void*, u32, u32);
|
using JobProcessor = void (*)(JobFunction, void*, void*, u32, u32);
|
||||||
|
|
||||||
enum class LoadFlags : u64 {
|
// Ignoring certain nodes will only stop them from being processed not tokenised (i.e. they will still be in the tree)
|
||||||
TRIANGULATE = 1 << 0,
|
enum class LoadFlags : u16
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
UNUSED = 1 << 0, // can be reused
|
||||||
IGNORE_GEOMETRY = 1 << 1,
|
IGNORE_GEOMETRY = 1 << 1,
|
||||||
IGNORE_BLEND_SHAPES = 1 << 2,
|
IGNORE_BLEND_SHAPES = 1 << 2,
|
||||||
|
IGNORE_CAMERAS = 1 << 3,
|
||||||
|
IGNORE_LIGHTS = 1 << 4,
|
||||||
|
IGNORE_TEXTURES = 1 << 5,
|
||||||
|
IGNORE_SKIN = 1 << 6,
|
||||||
|
IGNORE_BONES = 1 << 7,
|
||||||
|
IGNORE_PIVOTS = 1 << 8,
|
||||||
|
IGNORE_ANIMATIONS = 1 << 9,
|
||||||
|
IGNORE_MATERIALS = 1 << 10,
|
||||||
|
IGNORE_POSES = 1 << 11,
|
||||||
|
IGNORE_VIDEOS = 1 << 12,
|
||||||
|
IGNORE_LIMBS = 1 << 13,
|
||||||
|
IGNORE_MESHES = 1 << 14,
|
||||||
|
IGNORE_MODELS = 1 << 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr LoadFlags operator|(LoadFlags lhs, LoadFlags rhs)
|
||||||
struct Vec2
|
|
||||||
{
|
{
|
||||||
double x, y;
|
return static_cast<LoadFlags>(static_cast<u16>(lhs) | static_cast<u16>(rhs));
|
||||||
};
|
}
|
||||||
|
|
||||||
|
inline LoadFlags& operator|=(LoadFlags& lhs, LoadFlags rhs)
|
||||||
struct Vec3
|
|
||||||
{
|
{
|
||||||
double x, y, z;
|
return lhs = lhs | rhs;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
struct DVec2 { double x, y; };
|
||||||
|
struct DVec3 { double x, y, z; };
|
||||||
|
struct DVec4 { double x, y, z, w; };
|
||||||
|
struct DMatrix { double m[16]; /* last 4 are translation */ };
|
||||||
|
struct DQuat{ double x, y, z, w; };
|
||||||
|
|
||||||
struct Vec4
|
struct FVec2 { float x, y; };
|
||||||
{
|
struct FVec3 { float x, y, z; };
|
||||||
double x, y, z, w;
|
struct FVec4 { float x, y, z, w; };
|
||||||
};
|
struct FMatrix { float m[16]; };
|
||||||
|
struct FQuat{ float x, y, z, w; };
|
||||||
|
|
||||||
struct Matrix
|
|
||||||
{
|
|
||||||
double m[16]; // last 4 are translation
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Quat
|
|
||||||
{
|
|
||||||
double x, y, z, w;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
#define OFBX_SINGLE_PRECISION
|
||||||
|
#ifdef OFBX_SINGLE_PRECISION
|
||||||
|
// use floats for vertices, normals, uvs, ...
|
||||||
|
using Vec2 = FVec2;
|
||||||
|
using Vec3 = FVec3;
|
||||||
|
using Vec4 = FVec4;
|
||||||
|
using Matrix = FMatrix;
|
||||||
|
using Quat = FQuat;
|
||||||
|
#else
|
||||||
|
// use doubles for vertices, normals, uvs, ...
|
||||||
|
using Vec2 = DVec2;
|
||||||
|
using Vec3 = DVec3;
|
||||||
|
using Vec4 = DVec4;
|
||||||
|
using Matrix = DMatrix;
|
||||||
|
using Quat = DQuat;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct Color
|
struct Color
|
||||||
{
|
{
|
||||||
@@ -81,9 +106,10 @@ struct DataView
|
|||||||
i64 toI64() const;
|
i64 toI64() const;
|
||||||
int toInt() const;
|
int toInt() const;
|
||||||
u32 toU32() const;
|
u32 toU32() const;
|
||||||
|
bool toBool() const;
|
||||||
double toDouble() const;
|
double toDouble() const;
|
||||||
float toFloat() const;
|
float toFloat() const;
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
void toString(char(&out)[N]) const
|
void toString(char(&out)[N]) const
|
||||||
{
|
{
|
||||||
@@ -113,7 +139,8 @@ struct IElementProperty
|
|||||||
ARRAY_INT = 'i',
|
ARRAY_INT = 'i',
|
||||||
ARRAY_LONG = 'l',
|
ARRAY_LONG = 'l',
|
||||||
ARRAY_FLOAT = 'f',
|
ARRAY_FLOAT = 'f',
|
||||||
BINARY = 'R'
|
BINARY = 'R',
|
||||||
|
NONE = ' '
|
||||||
};
|
};
|
||||||
virtual ~IElementProperty() {}
|
virtual ~IElementProperty() {}
|
||||||
virtual Type getType() const = 0;
|
virtual Type getType() const = 0;
|
||||||
@@ -168,6 +195,8 @@ struct Object
|
|||||||
TEXTURE,
|
TEXTURE,
|
||||||
LIMB_NODE,
|
LIMB_NODE,
|
||||||
NULL_NODE,
|
NULL_NODE,
|
||||||
|
CAMERA,
|
||||||
|
LIGHT,
|
||||||
NODE_ATTRIBUTE,
|
NODE_ATTRIBUTE,
|
||||||
CLUSTER,
|
CLUSTER,
|
||||||
SKIN,
|
SKIN,
|
||||||
@@ -189,22 +218,22 @@ struct Object
|
|||||||
Object* resolveObjectLink(int idx) const;
|
Object* resolveObjectLink(int idx) const;
|
||||||
Object* resolveObjectLink(Type type, const char* property, int idx) const;
|
Object* resolveObjectLink(Type type, const char* property, int idx) const;
|
||||||
Object* resolveObjectLinkReverse(Type type) const;
|
Object* resolveObjectLinkReverse(Type type) const;
|
||||||
Object* getParent() const;
|
Object* getParent() const { return parent; }
|
||||||
|
|
||||||
RotationOrder getRotationOrder() const;
|
RotationOrder getRotationOrder() const;
|
||||||
Vec3 getRotationOffset() const;
|
DVec3 getRotationOffset() const;
|
||||||
Vec3 getRotationPivot() const;
|
DVec3 getRotationPivot() const;
|
||||||
Vec3 getPostRotation() const;
|
DVec3 getPostRotation() const;
|
||||||
Vec3 getScalingOffset() const;
|
DVec3 getScalingOffset() const;
|
||||||
Vec3 getScalingPivot() const;
|
DVec3 getScalingPivot() const;
|
||||||
Vec3 getPreRotation() const;
|
DVec3 getPreRotation() const;
|
||||||
Vec3 getLocalTranslation() const;
|
DVec3 getLocalTranslation() const;
|
||||||
Vec3 getLocalRotation() const;
|
DVec3 getLocalRotation() const;
|
||||||
Vec3 getLocalScaling() const;
|
DVec3 getLocalScaling() const;
|
||||||
Matrix getGlobalTransform() const;
|
DMatrix getGlobalTransform() const;
|
||||||
Matrix getLocalTransform() const;
|
DMatrix getLocalTransform() const;
|
||||||
Matrix evalLocal(const Vec3& translation, const Vec3& rotation) const;
|
DMatrix evalLocal(const DVec3& translation, const DVec3& rotation) const;
|
||||||
Matrix evalLocal(const Vec3& translation, const Vec3& rotation, const Vec3& scaling) const;
|
DMatrix evalLocal(const DVec3& translation, const DVec3& rotation, const DVec3& scaling) const;
|
||||||
bool isNode() const { return is_node; }
|
bool isNode() const { return is_node; }
|
||||||
|
|
||||||
|
|
||||||
@@ -214,11 +243,14 @@ struct Object
|
|||||||
}
|
}
|
||||||
|
|
||||||
u64 id;
|
u64 id;
|
||||||
|
u32 depth = 0xffFFffFF;
|
||||||
|
Object* parent = nullptr;
|
||||||
char name[128];
|
char name[128];
|
||||||
const IElement& element;
|
const IElement& element;
|
||||||
const Object* node_attribute;
|
const Object* node_attribute;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
friend struct Scene;
|
||||||
bool is_node;
|
bool is_node;
|
||||||
const Scene& scene;
|
const Scene& scene;
|
||||||
};
|
};
|
||||||
@@ -228,7 +260,7 @@ struct Pose : Object {
|
|||||||
static const Type s_type = Type::POSE;
|
static const Type s_type = Type::POSE;
|
||||||
Pose(const Scene& _scene, const IElement& _element);
|
Pose(const Scene& _scene, const IElement& _element);
|
||||||
|
|
||||||
virtual Matrix getMatrix() const = 0;
|
virtual DMatrix getMatrix() const = 0;
|
||||||
virtual const Object* getNode() const = 0;
|
virtual const Object* getNode() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -255,6 +287,124 @@ struct Texture : Object
|
|||||||
virtual DataView getEmbeddedData() const = 0;
|
virtual DataView getEmbeddedData() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Light : Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class LightType
|
||||||
|
{
|
||||||
|
POINT,
|
||||||
|
DIRECTIONAL,
|
||||||
|
SPOT,
|
||||||
|
AREA,
|
||||||
|
VOLUME,
|
||||||
|
COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DecayType
|
||||||
|
{
|
||||||
|
NO_DECAY,
|
||||||
|
LINEAR,
|
||||||
|
QUADRATIC,
|
||||||
|
CUBIC,
|
||||||
|
COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
Light(const Scene& _scene, const IElement& _element)
|
||||||
|
: Object(_scene, _element)
|
||||||
|
{
|
||||||
|
// Initialize the light properties here
|
||||||
|
}
|
||||||
|
|
||||||
|
// Light type
|
||||||
|
virtual LightType getLightType() const = 0;
|
||||||
|
|
||||||
|
// Light properties
|
||||||
|
virtual bool doesCastLight() const = 0;
|
||||||
|
virtual bool doesDrawVolumetricLight() const = 0;
|
||||||
|
virtual bool doesDrawGroundProjection() const = 0;
|
||||||
|
virtual bool doesDrawFrontFacingVolumetricLight() const = 0;
|
||||||
|
virtual Color getColor() const = 0;
|
||||||
|
virtual double getIntensity() const = 0;
|
||||||
|
virtual double getInnerAngle() const = 0;
|
||||||
|
virtual double getOuterAngle() const = 0;
|
||||||
|
virtual double getFog() const = 0;
|
||||||
|
virtual DecayType getDecayType() const = 0;
|
||||||
|
virtual double getDecayStart() const = 0;
|
||||||
|
|
||||||
|
// Near attenuation
|
||||||
|
virtual bool doesEnableNearAttenuation() const = 0;
|
||||||
|
virtual double getNearAttenuationStart() const = 0;
|
||||||
|
virtual double getNearAttenuationEnd() const = 0;
|
||||||
|
|
||||||
|
// Far attenuation
|
||||||
|
virtual bool doesEnableFarAttenuation() const = 0;
|
||||||
|
virtual double getFarAttenuationStart() const = 0;
|
||||||
|
virtual double getFarAttenuationEnd() const = 0;
|
||||||
|
|
||||||
|
// Shadows
|
||||||
|
virtual const Texture* getShadowTexture() const = 0;
|
||||||
|
virtual bool doesCastShadows() const = 0;
|
||||||
|
virtual Color getShadowColor() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Camera : Object
|
||||||
|
{
|
||||||
|
enum class ProjectionType
|
||||||
|
{
|
||||||
|
PERSPECTIVE,
|
||||||
|
ORTHOGRAPHIC,
|
||||||
|
COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ApertureMode // Used to determine how to calculate the FOV
|
||||||
|
{
|
||||||
|
HORIZANDVERT,
|
||||||
|
HORIZONTAL,
|
||||||
|
VERTICAL,
|
||||||
|
FOCALLENGTH,
|
||||||
|
COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class GateFit
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
VERTICAL,
|
||||||
|
HORIZONTAL,
|
||||||
|
FILL,
|
||||||
|
OVERSCAN,
|
||||||
|
STRETCH,
|
||||||
|
COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Type s_type = Type::CAMERA;
|
||||||
|
|
||||||
|
Camera(const Scene& _scene, const IElement& _element)
|
||||||
|
: Object(_scene, _element)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Type getType() const { return Type::CAMERA; }
|
||||||
|
virtual ProjectionType getProjectionType() const = 0;
|
||||||
|
virtual ApertureMode getApertureMode() const = 0;
|
||||||
|
|
||||||
|
virtual double getFilmHeight() const = 0;
|
||||||
|
virtual double getFilmWidth() const = 0;
|
||||||
|
|
||||||
|
virtual double getAspectHeight() const = 0;
|
||||||
|
virtual double getAspectWidth() const = 0;
|
||||||
|
|
||||||
|
virtual double getNearPlane() const = 0;
|
||||||
|
virtual double getFarPlane() const = 0;
|
||||||
|
virtual bool doesAutoComputeClipPanes() const = 0;
|
||||||
|
|
||||||
|
virtual GateFit getGateFit() const = 0;
|
||||||
|
virtual double getFilmAspectRatio() const = 0;
|
||||||
|
virtual double getFocalLength() const = 0;
|
||||||
|
virtual double getFocusDistance() const = 0;
|
||||||
|
|
||||||
|
virtual DVec3 getBackgroundColor() const = 0;
|
||||||
|
virtual DVec3 getInterestPosition() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct Material : Object
|
struct Material : Object
|
||||||
{
|
{
|
||||||
@@ -291,8 +441,8 @@ struct Cluster : Object
|
|||||||
virtual int getIndicesCount() const = 0;
|
virtual int getIndicesCount() const = 0;
|
||||||
virtual const double* getWeights() const = 0;
|
virtual const double* getWeights() const = 0;
|
||||||
virtual int getWeightsCount() const = 0;
|
virtual int getWeightsCount() const = 0;
|
||||||
virtual Matrix getTransformMatrix() const = 0;
|
virtual DMatrix getTransformMatrix() const = 0;
|
||||||
virtual Matrix getTransformLinkMatrix() const = 0;
|
virtual DMatrix getTransformLinkMatrix() const = 0;
|
||||||
virtual const Object* getLink() const = 0;
|
virtual const Object* getLink() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -341,26 +491,74 @@ struct NodeAttribute : Object
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Geometry : Object
|
struct Vec2Attributes {
|
||||||
{
|
const Vec2* values = nullptr;
|
||||||
|
const int* indices = nullptr;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
Vec2Attributes() {}
|
||||||
|
Vec2Attributes(const Vec2* v, const int* i, int c) : values(v), indices(i), count(c) {}
|
||||||
|
|
||||||
|
Vec2 get(int i) const { return indices ? values[indices[i]] : values[i]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vec3Attributes {
|
||||||
|
const Vec3* values = nullptr;
|
||||||
|
const int* indices = nullptr;
|
||||||
|
int count = 0;
|
||||||
|
int values_count = 0;
|
||||||
|
|
||||||
|
Vec3Attributes() {}
|
||||||
|
Vec3Attributes(const Vec3* v, const int* i, int c, int vc) : values(v), indices(i), count(c), values_count(vc) {}
|
||||||
|
|
||||||
|
Vec3 get(int i) const { return indices ? values[indices[i]] : values[i]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vec4Attributes {
|
||||||
|
const Vec4* values = nullptr;
|
||||||
|
const int* indices = nullptr;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
Vec4Attributes() {}
|
||||||
|
Vec4Attributes(const Vec4* v, const int* i, int c) : values(v), indices(i), count(c) {}
|
||||||
|
|
||||||
|
Vec4 get(int i) const { return indices ? values[indices[i]] : values[i]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// subset of polygons with same material
|
||||||
|
struct GeometryPartition {
|
||||||
|
struct Polygon {
|
||||||
|
const int from_vertex; // index into VecNAttributes::indices
|
||||||
|
const int vertex_count;
|
||||||
|
};
|
||||||
|
const Polygon* polygons;
|
||||||
|
const int polygon_count;
|
||||||
|
const int max_polygon_triangles; // max triangles in single polygon, can be used for preallocation
|
||||||
|
const int triangles_count; // number of triangles after polygon triangulation, can be used for preallocation
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GeometryData {
|
||||||
|
virtual ~GeometryData() {}
|
||||||
|
|
||||||
|
virtual Vec3Attributes getPositions() const = 0;
|
||||||
|
virtual Vec3Attributes getNormals() const = 0;
|
||||||
|
virtual Vec2Attributes getUVs(int index = 0) const = 0;
|
||||||
|
virtual Vec4Attributes getColors() const = 0;
|
||||||
|
virtual Vec3Attributes getTangents() const = 0;
|
||||||
|
virtual int getPartitionCount() const = 0;
|
||||||
|
virtual GeometryPartition getPartition(int partition_index) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Geometry : Object {
|
||||||
static const Type s_type = Type::GEOMETRY;
|
static const Type s_type = Type::GEOMETRY;
|
||||||
static const int s_uvs_max = 4;
|
static const int s_uvs_max = 4;
|
||||||
|
|
||||||
Geometry(const Scene& _scene, const IElement& _element);
|
Geometry(const Scene& _scene, const IElement& _element);
|
||||||
|
|
||||||
virtual const Vec3* getVertices() const = 0;
|
virtual const GeometryData& getGeometryData() const = 0;
|
||||||
virtual int getVertexCount() const = 0;
|
|
||||||
|
|
||||||
virtual const int* getFaceIndices() const = 0;
|
|
||||||
virtual int getIndexCount() const = 0;
|
|
||||||
|
|
||||||
virtual const Vec3* getNormals() const = 0;
|
|
||||||
virtual const Vec2* getUVs(int index = 0) const = 0;
|
|
||||||
virtual const Vec4* getColors() const = 0;
|
|
||||||
virtual const Vec3* getTangents() const = 0;
|
|
||||||
virtual const Skin* getSkin() const = 0;
|
virtual const Skin* getSkin() const = 0;
|
||||||
virtual const BlendShape* getBlendShape() const = 0;
|
virtual const BlendShape* getBlendShape() const = 0;
|
||||||
virtual const int* getMaterials() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -373,21 +571,27 @@ struct Shape : Object
|
|||||||
virtual const Vec3* getVertices() const = 0;
|
virtual const Vec3* getVertices() const = 0;
|
||||||
virtual int getVertexCount() const = 0;
|
virtual int getVertexCount() const = 0;
|
||||||
|
|
||||||
|
virtual const int* getIndices() const = 0;
|
||||||
|
virtual int getIndexCount() const = 0;
|
||||||
|
|
||||||
virtual const Vec3* getNormals() const = 0;
|
virtual const Vec3* getNormals() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Mesh : Object
|
struct Mesh : Object {
|
||||||
{
|
|
||||||
static const Type s_type = Type::MESH;
|
static const Type s_type = Type::MESH;
|
||||||
|
|
||||||
Mesh(const Scene& _scene, const IElement& _element);
|
Mesh(const Scene& _scene, const IElement& _element);
|
||||||
|
|
||||||
virtual const Pose* getPose() const = 0;
|
virtual const Pose* getPose() const = 0;
|
||||||
virtual const Geometry* getGeometry() const = 0;
|
virtual const Geometry* getGeometry() const = 0;
|
||||||
virtual Matrix getGeometricMatrix() const = 0;
|
virtual DMatrix getGeometricMatrix() const = 0;
|
||||||
virtual const Material* getMaterial(int idx) const = 0;
|
virtual const Material* getMaterial(int idx) const = 0;
|
||||||
virtual int getMaterialCount() const = 0;
|
virtual int getMaterialCount() const = 0;
|
||||||
|
// this will use data from `Geometry` if available and from `Mesh` otherwise
|
||||||
|
virtual const GeometryData& getGeometryData() const = 0;
|
||||||
|
virtual const Skin* getSkin() const = 0;
|
||||||
|
virtual const BlendShape* getBlendShape() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -429,8 +633,9 @@ struct AnimationCurveNode : Object
|
|||||||
|
|
||||||
AnimationCurveNode(const Scene& _scene, const IElement& _element);
|
AnimationCurveNode(const Scene& _scene, const IElement& _element);
|
||||||
|
|
||||||
|
virtual DataView getBoneLinkProperty() const = 0;
|
||||||
virtual const AnimationCurve* getCurve(int idx) const = 0;
|
virtual const AnimationCurve* getCurve(int idx) const = 0;
|
||||||
virtual Vec3 getNodeLocalTransform(double time) const = 0;
|
virtual DVec3 getNodeLocalTransform(double time) const = 0;
|
||||||
virtual const Object* getBone() const = 0;
|
virtual const Object* getBone() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -494,9 +699,11 @@ enum FrameRate
|
|||||||
|
|
||||||
struct GlobalSettings
|
struct GlobalSettings
|
||||||
{
|
{
|
||||||
UpVector UpAxis = UpVector_AxisX;
|
UpVector UpAxis = UpVector_AxisY;
|
||||||
int UpAxisSign = 1;
|
int UpAxisSign = 1;
|
||||||
FrontVector FrontAxis = FrontVector_ParityOdd;
|
// this seems to be 1-2 in Autodesk (odd/even parity), and 0-2 in Blender (axis as in UpAxis)
|
||||||
|
// I recommend to ignore FrontAxis and use just UpVector
|
||||||
|
int FrontAxis = 1;
|
||||||
int FrontAxisSign = 1;
|
int FrontAxisSign = 1;
|
||||||
CoordSystem CoordAxis = CoordSystem_RightHanded;
|
CoordSystem CoordAxis = CoordSystem_RightHanded;
|
||||||
int CoordAxisSign = 1;
|
int CoordAxisSign = 1;
|
||||||
@@ -522,30 +729,102 @@ struct GlobalInfo
|
|||||||
struct IScene
|
struct IScene
|
||||||
{
|
{
|
||||||
virtual void destroy() = 0;
|
virtual void destroy() = 0;
|
||||||
|
|
||||||
|
// Root Node
|
||||||
virtual const IElement* getRootElement() const = 0;
|
virtual const IElement* getRootElement() const = 0;
|
||||||
virtual const Object* getRoot() const = 0;
|
virtual const Object* getRoot() const = 0;
|
||||||
virtual const TakeInfo* getTakeInfo(const char* name) const = 0;
|
|
||||||
|
// Meshes
|
||||||
virtual int getMeshCount() const = 0;
|
virtual int getMeshCount() const = 0;
|
||||||
virtual float getSceneFrameRate() const = 0;
|
|
||||||
virtual const GlobalInfo* getGlobalInfo() const = 0;
|
|
||||||
virtual const GlobalSettings* getGlobalSettings() const = 0;
|
|
||||||
virtual const Mesh* getMesh(int index) const = 0;
|
virtual const Mesh* getMesh(int index) const = 0;
|
||||||
|
|
||||||
|
// Geometry
|
||||||
|
virtual int getGeometryCount() const = 0;
|
||||||
|
virtual const Geometry* getGeometry(int index) const = 0;
|
||||||
|
|
||||||
|
// Animations
|
||||||
virtual int getAnimationStackCount() const = 0;
|
virtual int getAnimationStackCount() const = 0;
|
||||||
virtual const AnimationStack* getAnimationStack(int index) const = 0;
|
virtual const AnimationStack* getAnimationStack(int index) const = 0;
|
||||||
|
|
||||||
|
// Cameras
|
||||||
|
virtual int getCameraCount() const = 0;
|
||||||
|
virtual const Camera* getCamera(int index) const = 0;
|
||||||
|
|
||||||
|
// Lights
|
||||||
|
virtual int getLightCount() const = 0;
|
||||||
|
virtual const Light* getLight(int index) const = 0;
|
||||||
|
|
||||||
|
// Scene Objects (Everything in scene)
|
||||||
virtual const Object* const* getAllObjects() const = 0;
|
virtual const Object* const* getAllObjects() const = 0;
|
||||||
virtual int getAllObjectCount() const = 0;
|
virtual int getAllObjectCount() const = 0;
|
||||||
|
|
||||||
|
// Embedded files/Data
|
||||||
virtual int getEmbeddedDataCount() const = 0;
|
virtual int getEmbeddedDataCount() const = 0;
|
||||||
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;
|
||||||
|
// data are encoded in returned property and all ->next properties
|
||||||
|
virtual const IElementProperty* getEmbeddedBase64Data(int index) const = 0;
|
||||||
|
|
||||||
|
// Scene Misc
|
||||||
|
virtual const TakeInfo* getTakeInfo(const char* name) const = 0;
|
||||||
|
virtual float getSceneFrameRate() const = 0;
|
||||||
|
virtual const GlobalSettings* getGlobalSettings() const = 0;
|
||||||
|
virtual const GlobalInfo* getGlobalInfo() const = 0;
|
||||||
|
|
||||||
virtual ~IScene() {}
|
virtual ~IScene() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
IScene* load(const u8* data, int size, u64 flags, JobProcessor job_processor = nullptr, void* job_user_ptr = nullptr);
|
IScene* load(const u8* data, usize size, u16 flags, JobProcessor job_processor = nullptr, void* job_user_ptr = nullptr);
|
||||||
const char* getError();
|
const char* getError();
|
||||||
double fbxTimeToSeconds(i64 value);
|
double fbxTimeToSeconds(i64 value);
|
||||||
i64 secondsToFbxTime(double value);
|
i64 secondsToFbxTime(double value);
|
||||||
|
|
||||||
|
// TODO nonconvex
|
||||||
|
inline u32 triangulate(const GeometryData& geom, const GeometryPartition::Polygon& polygon, int* tri_indices) {
|
||||||
|
if (polygon.vertex_count < 3) return 0;
|
||||||
|
if (polygon.vertex_count == 3) {
|
||||||
|
tri_indices[0] = polygon.from_vertex;
|
||||||
|
tri_indices[1] = polygon.from_vertex + 1;
|
||||||
|
tri_indices[2] = polygon.from_vertex + 2;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
else if (polygon.vertex_count == 4) {
|
||||||
|
tri_indices[0] = polygon.from_vertex + 0;
|
||||||
|
tri_indices[1] = polygon.from_vertex + 1;
|
||||||
|
tri_indices[2] = polygon.from_vertex + 2;
|
||||||
|
|
||||||
|
tri_indices[3] = polygon.from_vertex + 0;
|
||||||
|
tri_indices[4] = polygon.from_vertex + 2;
|
||||||
|
tri_indices[5] = polygon.from_vertex + 3;
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int tri = 0; tri < polygon.vertex_count - 2; ++tri) {
|
||||||
|
tri_indices[tri * 3 + 0] = polygon.from_vertex;
|
||||||
|
tri_indices[tri * 3 + 1] = polygon.from_vertex + 1 + tri;
|
||||||
|
tri_indices[tri * 3 + 2] = polygon.from_vertex + 2 + tri;
|
||||||
|
}
|
||||||
|
return 3 * (polygon.vertex_count - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace ofbx
|
} // namespace ofbx
|
||||||
|
|
||||||
|
#ifdef OFBX_DEFAULT_DELETER
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
template <> struct ::std::default_delete<ofbx::IScene>
|
||||||
|
{
|
||||||
|
default_delete() = default;
|
||||||
|
template <class U> constexpr default_delete(default_delete<U>) noexcept {}
|
||||||
|
void operator()(ofbx::IScene* scene) const noexcept
|
||||||
|
{
|
||||||
|
if (scene)
|
||||||
|
{
|
||||||
|
scene->destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,7 @@
|
|||||||
/* miniz.c v1.16 beta r1 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
|
#ifndef MINIZ_EXPORT
|
||||||
|
#define MINIZ_EXPORT
|
||||||
|
#endif
|
||||||
|
/* miniz.c 3.0.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
|
||||||
See "unlicense" statement at the end of this file.
|
See "unlicense" statement at the end of this file.
|
||||||
Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
|
Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
|
||||||
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
|
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
|
||||||
@@ -24,7 +27,7 @@
|
|||||||
zlib replacement in many apps:
|
zlib replacement in many apps:
|
||||||
The z_stream struct, optional memory allocation callbacks
|
The z_stream struct, optional memory allocation callbacks
|
||||||
deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
|
deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
|
||||||
inflateInit/inflateInit2/inflate/inflateEnd
|
inflateInit/inflateInit2/inflate/inflateReset/inflateEnd
|
||||||
compress, compress2, compressBound, uncompress
|
compress, compress2, compressBound, uncompress
|
||||||
CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
|
CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
|
||||||
Supports raw deflate streams or standard zlib streams with adler-32 checking.
|
Supports raw deflate streams or standard zlib streams with adler-32 checking.
|
||||||
@@ -95,7 +98,7 @@
|
|||||||
possibility that the archive's central directory could be lost with this method if anything goes wrong, though.
|
possibility that the archive's central directory could be lost with this method if anything goes wrong, though.
|
||||||
|
|
||||||
- ZIP archive support limitations:
|
- ZIP archive support limitations:
|
||||||
No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
|
No spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
|
||||||
Requires streams capable of seeking.
|
Requires streams capable of seeking.
|
||||||
|
|
||||||
* This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
|
* This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
|
||||||
@@ -114,10 +117,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Defines to completely disable specific portions of miniz.c:
|
/* Defines to completely disable specific portions of miniz.c:
|
||||||
If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. */
|
If all macros here are defined the only functionality remaining will be CRC-32 and adler-32. */
|
||||||
|
|
||||||
/* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */
|
/* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */
|
||||||
/*#define MINIZ_NO_STDIO */
|
/*#define MINIZ_NO_STDIO */
|
||||||
@@ -127,6 +128,12 @@
|
|||||||
/* The current downside is the times written to your archives will be from 1979. */
|
/* The current downside is the times written to your archives will be from 1979. */
|
||||||
/*#define MINIZ_NO_TIME */
|
/*#define MINIZ_NO_TIME */
|
||||||
|
|
||||||
|
/* Define MINIZ_NO_DEFLATE_APIS to disable all compression API's. */
|
||||||
|
/*#define MINIZ_NO_DEFLATE_APIS */
|
||||||
|
|
||||||
|
/* Define MINIZ_NO_INFLATE_APIS to disable all decompression API's. */
|
||||||
|
/*#define MINIZ_NO_INFLATE_APIS */
|
||||||
|
|
||||||
/* Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. */
|
/* Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. */
|
||||||
/*#define MINIZ_NO_ARCHIVE_APIS */
|
/*#define MINIZ_NO_ARCHIVE_APIS */
|
||||||
|
|
||||||
@@ -145,6 +152,14 @@
|
|||||||
functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */
|
functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */
|
||||||
/*#define MINIZ_NO_MALLOC */
|
/*#define MINIZ_NO_MALLOC */
|
||||||
|
|
||||||
|
#ifdef MINIZ_NO_INFLATE_APIS
|
||||||
|
#define MINIZ_NO_ARCHIVE_APIS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MINIZ_NO_DEFLATE_APIS
|
||||||
|
#define MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
|
#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
|
||||||
/* TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux */
|
/* TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux */
|
||||||
#define MINIZ_NO_TIME
|
#define MINIZ_NO_TIME
|
||||||
@@ -159,21 +174,55 @@
|
|||||||
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
|
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
|
||||||
/* MINIZ_X86_OR_X64_CPU is only used to help set the below macros. */
|
/* MINIZ_X86_OR_X64_CPU is only used to help set the below macros. */
|
||||||
#define MINIZ_X86_OR_X64_CPU 1
|
#define MINIZ_X86_OR_X64_CPU 1
|
||||||
|
#else
|
||||||
|
#define MINIZ_X86_OR_X64_CPU 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
|
/* Set MINIZ_LITTLE_ENDIAN only if not set */
|
||||||
|
#if !defined(MINIZ_LITTLE_ENDIAN)
|
||||||
|
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
|
||||||
|
|
||||||
|
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||||
/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
|
/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
|
||||||
#define MINIZ_LITTLE_ENDIAN 1
|
#define MINIZ_LITTLE_ENDIAN 1
|
||||||
|
#else
|
||||||
|
#define MINIZ_LITTLE_ENDIAN 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if MINIZ_X86_OR_X64_CPU
|
||||||
|
#define MINIZ_LITTLE_ENDIAN 1
|
||||||
|
#else
|
||||||
|
#define MINIZ_LITTLE_ENDIAN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Using unaligned loads and stores causes errors when using UBSan */
|
||||||
|
#if defined(__has_feature)
|
||||||
|
#if __has_feature(undefined_behavior_sanitizer)
|
||||||
|
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES only if not set */
|
||||||
|
#if !defined(MINIZ_USE_UNALIGNED_LOADS_AND_STORES)
|
||||||
#if MINIZ_X86_OR_X64_CPU
|
#if MINIZ_X86_OR_X64_CPU
|
||||||
/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. */
|
/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. */
|
||||||
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
|
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
|
||||||
|
#define MINIZ_UNALIGNED_USE_MEMCPY
|
||||||
|
#else
|
||||||
|
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
|
#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
|
||||||
/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). */
|
/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). */
|
||||||
#define MINIZ_HAS_64BIT_REGISTERS 1
|
#define MINIZ_HAS_64BIT_REGISTERS 1
|
||||||
|
#else
|
||||||
|
#define MINIZ_HAS_64BIT_REGISTERS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -186,15 +235,15 @@ extern "C" {
|
|||||||
typedef unsigned long mz_ulong;
|
typedef unsigned long mz_ulong;
|
||||||
|
|
||||||
/* mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. */
|
/* mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. */
|
||||||
void mz_free(void *p);
|
MINIZ_EXPORT void mz_free(void *p);
|
||||||
|
|
||||||
#define MZ_ADLER32_INIT (1)
|
#define MZ_ADLER32_INIT (1)
|
||||||
/* mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. */
|
/* mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. */
|
||||||
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
|
MINIZ_EXPORT mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
|
||||||
|
|
||||||
#define MZ_CRC32_INIT (0)
|
#define MZ_CRC32_INIT (0)
|
||||||
/* mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. */
|
/* mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. */
|
||||||
mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
|
MINIZ_EXPORT mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
|
||||||
|
|
||||||
/* Compression strategies. */
|
/* Compression strategies. */
|
||||||
enum
|
enum
|
||||||
@@ -210,26 +259,26 @@ enum
|
|||||||
#define MZ_DEFLATED 8
|
#define MZ_DEFLATED 8
|
||||||
|
|
||||||
/* Heap allocation callbacks.
|
/* Heap allocation callbacks.
|
||||||
Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. */
|
Note that mz_alloc_func parameter types purposely differ from zlib's: items/size is size_t, not unsigned long. */
|
||||||
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
|
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
|
||||||
typedef void(*mz_free_func)(void *opaque, void *address);
|
typedef void (*mz_free_func)(void *opaque, void *address);
|
||||||
typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
|
typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
|
||||||
|
|
||||||
/* Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. */
|
/* Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MZ_NO_COMPRESSION = 0,
|
MZ_NO_COMPRESSION = 0,
|
||||||
MZ_BEST_SPEED = 1,
|
MZ_BEST_SPEED = 1,
|
||||||
MZ_BEST_COMPRESSION = 9,
|
MZ_BEST_COMPRESSION = 9,
|
||||||
MZ_UBER_COMPRESSION = 10,
|
MZ_UBER_COMPRESSION = 10,
|
||||||
MZ_DEFAULT_LEVEL = 6,
|
MZ_DEFAULT_LEVEL = 6,
|
||||||
MZ_DEFAULT_COMPRESSION = -1
|
MZ_DEFAULT_COMPRESSION = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MZ_VERSION "10.0.0"
|
#define MZ_VERSION "11.0.2"
|
||||||
#define MZ_VERNUM 0xA000
|
#define MZ_VERNUM 0xB002
|
||||||
#define MZ_VER_MAJOR 10
|
#define MZ_VER_MAJOR 11
|
||||||
#define MZ_VER_MINOR 0
|
#define MZ_VER_MINOR 2
|
||||||
#define MZ_VER_REVISION 0
|
#define MZ_VER_REVISION 0
|
||||||
#define MZ_VER_SUBREVISION 0
|
#define MZ_VER_SUBREVISION 0
|
||||||
|
|
||||||
@@ -292,7 +341,9 @@ typedef struct mz_stream_s
|
|||||||
typedef mz_stream *mz_streamp;
|
typedef mz_stream *mz_streamp;
|
||||||
|
|
||||||
/* Returns the version string of miniz.c. */
|
/* Returns the version string of miniz.c. */
|
||||||
const char *mz_version(void);
|
MINIZ_EXPORT const char *mz_version(void);
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||||
|
|
||||||
/* mz_deflateInit() initializes a compressor with default options: */
|
/* mz_deflateInit() initializes a compressor with default options: */
|
||||||
/* Parameters: */
|
/* Parameters: */
|
||||||
@@ -305,17 +356,17 @@ const char *mz_version(void);
|
|||||||
/* MZ_STREAM_ERROR if the stream is bogus. */
|
/* MZ_STREAM_ERROR if the stream is bogus. */
|
||||||
/* MZ_PARAM_ERROR if the input parameters are bogus. */
|
/* MZ_PARAM_ERROR if the input parameters are bogus. */
|
||||||
/* MZ_MEM_ERROR on out of memory. */
|
/* MZ_MEM_ERROR on out of memory. */
|
||||||
int mz_deflateInit(mz_streamp pStream, int level);
|
MINIZ_EXPORT int mz_deflateInit(mz_streamp pStream, int level);
|
||||||
|
|
||||||
/* mz_deflateInit2() is like mz_deflate(), except with more control: */
|
/* mz_deflateInit2() is like mz_deflate(), except with more control: */
|
||||||
/* Additional parameters: */
|
/* Additional parameters: */
|
||||||
/* method must be MZ_DEFLATED */
|
/* method must be MZ_DEFLATED */
|
||||||
/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) */
|
/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) */
|
||||||
/* mem_level must be between [1, 9] (it's checked but ignored by miniz.c) */
|
/* mem_level must be between [1, 9] (it's checked but ignored by miniz.c) */
|
||||||
int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
|
MINIZ_EXPORT int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
|
||||||
|
|
||||||
/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). */
|
/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). */
|
||||||
int mz_deflateReset(mz_streamp pStream);
|
MINIZ_EXPORT int mz_deflateReset(mz_streamp pStream);
|
||||||
|
|
||||||
/* mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. */
|
/* mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. */
|
||||||
/* Parameters: */
|
/* Parameters: */
|
||||||
@@ -327,31 +378,38 @@ int mz_deflateReset(mz_streamp pStream);
|
|||||||
/* MZ_STREAM_ERROR if the stream is bogus. */
|
/* MZ_STREAM_ERROR if the stream is bogus. */
|
||||||
/* MZ_PARAM_ERROR if one of the parameters is invalid. */
|
/* MZ_PARAM_ERROR if one of the parameters is invalid. */
|
||||||
/* MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) */
|
/* MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) */
|
||||||
int mz_deflate(mz_streamp pStream, int flush);
|
MINIZ_EXPORT int mz_deflate(mz_streamp pStream, int flush);
|
||||||
|
|
||||||
/* mz_deflateEnd() deinitializes a compressor: */
|
/* mz_deflateEnd() deinitializes a compressor: */
|
||||||
/* Return values: */
|
/* Return values: */
|
||||||
/* MZ_OK on success. */
|
/* MZ_OK on success. */
|
||||||
/* MZ_STREAM_ERROR if the stream is bogus. */
|
/* MZ_STREAM_ERROR if the stream is bogus. */
|
||||||
int mz_deflateEnd(mz_streamp pStream);
|
MINIZ_EXPORT int mz_deflateEnd(mz_streamp pStream);
|
||||||
|
|
||||||
/* mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. */
|
/* mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. */
|
||||||
mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
|
MINIZ_EXPORT mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
|
||||||
|
|
||||||
/* Single-call compression functions mz_compress() and mz_compress2(): */
|
/* Single-call compression functions mz_compress() and mz_compress2(): */
|
||||||
/* Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. */
|
/* Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. */
|
||||||
int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
|
MINIZ_EXPORT int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
|
||||||
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
|
MINIZ_EXPORT int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
|
||||||
|
|
||||||
/* mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). */
|
/* mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). */
|
||||||
mz_ulong mz_compressBound(mz_ulong source_len);
|
MINIZ_EXPORT mz_ulong mz_compressBound(mz_ulong source_len);
|
||||||
|
|
||||||
|
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_INFLATE_APIS
|
||||||
|
|
||||||
/* Initializes a decompressor. */
|
/* Initializes a decompressor. */
|
||||||
int mz_inflateInit(mz_streamp pStream);
|
MINIZ_EXPORT int mz_inflateInit(mz_streamp pStream);
|
||||||
|
|
||||||
/* mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: */
|
/* mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: */
|
||||||
/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). */
|
/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). */
|
||||||
int mz_inflateInit2(mz_streamp pStream, int window_bits);
|
MINIZ_EXPORT int mz_inflateInit2(mz_streamp pStream, int window_bits);
|
||||||
|
|
||||||
|
/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_inflateEnd() followed by mz_inflateInit()/mz_inflateInit2(). */
|
||||||
|
MINIZ_EXPORT int mz_inflateReset(mz_streamp pStream);
|
||||||
|
|
||||||
/* Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. */
|
/* Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. */
|
||||||
/* Parameters: */
|
/* Parameters: */
|
||||||
@@ -367,17 +425,19 @@ int mz_inflateInit2(mz_streamp pStream, int window_bits);
|
|||||||
/* MZ_PARAM_ERROR if one of the parameters is invalid. */
|
/* MZ_PARAM_ERROR if one of the parameters is invalid. */
|
||||||
/* MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again */
|
/* MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again */
|
||||||
/* with more input data, or with more room in the output buffer (except when using single call decompression, described above). */
|
/* with more input data, or with more room in the output buffer (except when using single call decompression, described above). */
|
||||||
int mz_inflate(mz_streamp pStream, int flush);
|
MINIZ_EXPORT int mz_inflate(mz_streamp pStream, int flush);
|
||||||
|
|
||||||
/* Deinitializes a decompressor. */
|
/* Deinitializes a decompressor. */
|
||||||
int mz_inflateEnd(mz_streamp pStream);
|
MINIZ_EXPORT int mz_inflateEnd(mz_streamp pStream);
|
||||||
|
|
||||||
/* Single-call decompression. */
|
/* Single-call decompression. */
|
||||||
/* Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. */
|
/* Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. */
|
||||||
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
|
MINIZ_EXPORT int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
|
||||||
|
MINIZ_EXPORT int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len);
|
||||||
|
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||||
|
|
||||||
/* Returns a string description of the specified error code, or NULL if the error code is invalid. */
|
/* Returns a string description of the specified error code, or NULL if the error code is invalid. */
|
||||||
const char *mz_error(int err);
|
MINIZ_EXPORT const char *mz_error(int err);
|
||||||
|
|
||||||
/* Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. */
|
/* Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. */
|
||||||
/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. */
|
/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. */
|
||||||
@@ -425,6 +485,8 @@ typedef void *const voidpc;
|
|||||||
#define free_func mz_free_func
|
#define free_func mz_free_func
|
||||||
#define internal_state mz_internal_state
|
#define internal_state mz_internal_state
|
||||||
#define z_stream mz_stream
|
#define z_stream mz_stream
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||||
#define deflateInit mz_deflateInit
|
#define deflateInit mz_deflateInit
|
||||||
#define deflateInit2 mz_deflateInit2
|
#define deflateInit2 mz_deflateInit2
|
||||||
#define deflateReset mz_deflateReset
|
#define deflateReset mz_deflateReset
|
||||||
@@ -434,11 +496,18 @@ typedef void *const voidpc;
|
|||||||
#define compress mz_compress
|
#define compress mz_compress
|
||||||
#define compress2 mz_compress2
|
#define compress2 mz_compress2
|
||||||
#define compressBound mz_compressBound
|
#define compressBound mz_compressBound
|
||||||
|
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_INFLATE_APIS
|
||||||
#define inflateInit mz_inflateInit
|
#define inflateInit mz_inflateInit
|
||||||
#define inflateInit2 mz_inflateInit2
|
#define inflateInit2 mz_inflateInit2
|
||||||
|
#define inflateReset mz_inflateReset
|
||||||
#define inflate mz_inflate
|
#define inflate mz_inflate
|
||||||
#define inflateEnd mz_inflateEnd
|
#define inflateEnd mz_inflateEnd
|
||||||
#define uncompress mz_uncompress
|
#define uncompress mz_uncompress
|
||||||
|
#define uncompress2 mz_uncompress2
|
||||||
|
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||||
|
|
||||||
#define crc32 mz_crc32
|
#define crc32 mz_crc32
|
||||||
#define adler32 mz_adler32
|
#define adler32 mz_adler32
|
||||||
#define MAX_WBITS 15
|
#define MAX_WBITS 15
|
||||||
@@ -459,11 +528,18 @@ typedef void *const voidpc;
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------- Types and macros */
|
/* ------------------- Types and macros */
|
||||||
typedef unsigned char mz_uint8;
|
typedef unsigned char mz_uint8;
|
||||||
@@ -495,7 +571,8 @@ typedef int mz_bool;
|
|||||||
#ifdef MINIZ_NO_TIME
|
#ifdef MINIZ_NO_TIME
|
||||||
typedef struct mz_dummy_time_t_tag
|
typedef struct mz_dummy_time_t_tag
|
||||||
{
|
{
|
||||||
int m_dummy;
|
mz_uint32 m_dummy1;
|
||||||
|
mz_uint32 m_dummy2;
|
||||||
} mz_dummy_time_t;
|
} mz_dummy_time_t;
|
||||||
#define MZ_TIME_T mz_dummy_time_t
|
#define MZ_TIME_T mz_dummy_time_t
|
||||||
#else
|
#else
|
||||||
@@ -506,7 +583,7 @@ typedef struct mz_dummy_time_t_tag
|
|||||||
|
|
||||||
#ifdef MINIZ_NO_MALLOC
|
#ifdef MINIZ_NO_MALLOC
|
||||||
#define MZ_MALLOC(x) NULL
|
#define MZ_MALLOC(x) NULL
|
||||||
#define MZ_FREE(x) (void) x, ((void)0)
|
#define MZ_FREE(x) (void)x, ((void)0)
|
||||||
#define MZ_REALLOC(p, x) NULL
|
#define MZ_REALLOC(p, x) NULL
|
||||||
#else
|
#else
|
||||||
#define MZ_MALLOC(x) malloc(x)
|
#define MZ_MALLOC(x) malloc(x)
|
||||||
@@ -517,8 +594,10 @@ typedef struct mz_dummy_time_t_tag
|
|||||||
#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))
|
#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b))
|
#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
|
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
|
||||||
|
#define MZ_CLEAR_ARR(obj) memset((obj), 0, sizeof(obj))
|
||||||
|
#define MZ_CLEAR_PTR(obj) memset((obj), 0, sizeof(*obj))
|
||||||
|
|
||||||
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES &&MINIZ_LITTLE_ENDIAN
|
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
|
||||||
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
|
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
|
||||||
#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
|
#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
|
||||||
#else
|
#else
|
||||||
@@ -540,9 +619,9 @@ typedef struct mz_dummy_time_t_tag
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void *miniz_def_alloc_func(void *opaque, size_t items, size_t size);
|
extern MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size);
|
||||||
extern void miniz_def_free_func(void *opaque, void *address);
|
extern MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address);
|
||||||
extern void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size);
|
extern MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size);
|
||||||
|
|
||||||
#define MZ_UINT16_MAX (0xFFFFU)
|
#define MZ_UINT16_MAX (0xFFFFU)
|
||||||
#define MZ_UINT32_MAX (0xFFFFFFFFU)
|
#define MZ_UINT32_MAX (0xFFFFFFFFU)
|
||||||
@@ -550,9 +629,11 @@ extern void *miniz_def_realloc_func(void *opaque, void *address, size_t items, s
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -600,11 +681,11 @@ enum
|
|||||||
/* Function returns a pointer to the compressed data, or NULL on failure. */
|
/* Function returns a pointer to the compressed data, or NULL on failure. */
|
||||||
/* *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. */
|
/* *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. */
|
||||||
/* The caller must free() the returned block when it's no longer needed. */
|
/* The caller must free() the returned block when it's no longer needed. */
|
||||||
void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
|
MINIZ_EXPORT void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
|
||||||
|
|
||||||
/* tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. */
|
/* tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. */
|
||||||
/* Returns 0 on failure. */
|
/* Returns 0 on failure. */
|
||||||
size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
|
MINIZ_EXPORT size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
|
||||||
|
|
||||||
/* Compresses an image to a compressed PNG file in memory. */
|
/* Compresses an image to a compressed PNG file in memory. */
|
||||||
/* On entry: */
|
/* On entry: */
|
||||||
@@ -616,14 +697,14 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void
|
|||||||
/* Function returns a pointer to the compressed data, or NULL on failure. */
|
/* Function returns a pointer to the compressed data, or NULL on failure. */
|
||||||
/* *pLen_out will be set to the size of the PNG image file. */
|
/* *pLen_out will be set to the size of the PNG image file. */
|
||||||
/* The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. */
|
/* The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. */
|
||||||
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
|
MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
|
||||||
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
|
MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
|
||||||
|
|
||||||
/* Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. */
|
/* Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. */
|
||||||
typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
|
typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
|
||||||
|
|
||||||
/* tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. */
|
/* tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. */
|
||||||
mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
MINIZ_EXPORT mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -663,8 +744,7 @@ enum
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. */
|
/* The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. */
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
TDEFL_STATUS_BAD_PARAM = -2,
|
TDEFL_STATUS_BAD_PARAM = -2,
|
||||||
TDEFL_STATUS_PUT_BUF_FAILED = -1,
|
TDEFL_STATUS_PUT_BUF_FAILED = -1,
|
||||||
TDEFL_STATUS_OKAY = 0,
|
TDEFL_STATUS_OKAY = 0,
|
||||||
@@ -672,8 +752,7 @@ typedef enum
|
|||||||
} tdefl_status;
|
} tdefl_status;
|
||||||
|
|
||||||
/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */
|
/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
TDEFL_NO_FLUSH = 0,
|
TDEFL_NO_FLUSH = 0,
|
||||||
TDEFL_SYNC_FLUSH = 2,
|
TDEFL_SYNC_FLUSH = 2,
|
||||||
TDEFL_FULL_FLUSH = 3,
|
TDEFL_FULL_FLUSH = 3,
|
||||||
@@ -713,37 +792,43 @@ typedef struct
|
|||||||
/* pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. */
|
/* pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. */
|
||||||
/* If pBut_buf_func is NULL the user should always call the tdefl_compress() API. */
|
/* If pBut_buf_func is NULL the user should always call the tdefl_compress() API. */
|
||||||
/* flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) */
|
/* flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) */
|
||||||
tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
MINIZ_EXPORT tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||||
|
|
||||||
/* Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. */
|
/* Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. */
|
||||||
tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);
|
MINIZ_EXPORT tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);
|
||||||
|
|
||||||
/* tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. */
|
/* tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. */
|
||||||
/* tdefl_compress_buffer() always consumes the entire input buffer. */
|
/* tdefl_compress_buffer() always consumes the entire input buffer. */
|
||||||
tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
|
MINIZ_EXPORT tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
|
||||||
|
|
||||||
tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
|
MINIZ_EXPORT tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
|
||||||
mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
|
MINIZ_EXPORT mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
|
||||||
|
|
||||||
/* Create tdefl_compress() flags given zlib-style compression parameters. */
|
/* Create tdefl_compress() flags given zlib-style compression parameters. */
|
||||||
/* level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) */
|
/* level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) */
|
||||||
/* window_bits may be -15 (raw deflate) or 15 (zlib) */
|
/* window_bits may be -15 (raw deflate) or 15 (zlib) */
|
||||||
/* strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED */
|
/* strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED */
|
||||||
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
|
MINIZ_EXPORT mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_MALLOC
|
||||||
/* Allocate the tdefl_compressor structure in C so that */
|
/* Allocate the tdefl_compressor structure in C so that */
|
||||||
/* non-C language bindings to tdefl_ API don't need to worry about */
|
/* non-C language bindings to tdefl_ API don't need to worry about */
|
||||||
/* structure size and allocation mechanism. */
|
/* structure size and allocation mechanism. */
|
||||||
tdefl_compressor *tdefl_compressor_alloc();
|
MINIZ_EXPORT tdefl_compressor *tdefl_compressor_alloc(void);
|
||||||
void tdefl_compressor_free(tdefl_compressor *pComp);
|
MINIZ_EXPORT void tdefl_compressor_free(tdefl_compressor *pComp);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#pragma once
|
|
||||||
|
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
/* ------------------- Low-level Decompression API Definitions */
|
/* ------------------- Low-level Decompression API Definitions */
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_INFLATE_APIS
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -768,34 +853,34 @@ enum
|
|||||||
/* Function returns a pointer to the decompressed data, or NULL on failure. */
|
/* Function returns a pointer to the decompressed data, or NULL on failure. */
|
||||||
/* *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. */
|
/* *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. */
|
||||||
/* The caller must call mz_free() on the returned block when it's no longer needed. */
|
/* The caller must call mz_free() on the returned block when it's no longer needed. */
|
||||||
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
|
MINIZ_EXPORT void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
|
||||||
|
|
||||||
/* tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. */
|
/* tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. */
|
||||||
/* Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. */
|
/* Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. */
|
||||||
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
|
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
|
||||||
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
|
MINIZ_EXPORT size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
|
||||||
|
|
||||||
/* tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. */
|
/* tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. */
|
||||||
/* Returns 1 on success or 0 on failure. */
|
/* Returns 1 on success or 0 on failure. */
|
||||||
typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
|
typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
|
||||||
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
MINIZ_EXPORT int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||||
|
|
||||||
struct tinfl_decompressor_tag;
|
struct tinfl_decompressor_tag;
|
||||||
typedef struct tinfl_decompressor_tag tinfl_decompressor;
|
typedef struct tinfl_decompressor_tag tinfl_decompressor;
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_MALLOC
|
||||||
/* Allocate the tinfl_decompressor structure in C so that */
|
/* Allocate the tinfl_decompressor structure in C so that */
|
||||||
/* non-C language bindings to tinfl_ API don't need to worry about */
|
/* non-C language bindings to tinfl_ API don't need to worry about */
|
||||||
/* structure size and allocation mechanism. */
|
/* structure size and allocation mechanism. */
|
||||||
|
MINIZ_EXPORT tinfl_decompressor *tinfl_decompressor_alloc(void);
|
||||||
tinfl_decompressor *tinfl_decompressor_alloc();
|
MINIZ_EXPORT void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
|
||||||
void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
|
#endif
|
||||||
|
|
||||||
/* Max size of LZ dictionary. */
|
/* Max size of LZ dictionary. */
|
||||||
#define TINFL_LZ_DICT_SIZE 32768
|
#define TINFL_LZ_DICT_SIZE 32768
|
||||||
|
|
||||||
/* Return status. */
|
/* Return status. */
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
/* This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data */
|
/* This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data */
|
||||||
/* is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly). */
|
/* is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly). */
|
||||||
/* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */
|
/* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */
|
||||||
@@ -839,7 +924,7 @@ typedef enum
|
|||||||
|
|
||||||
/* Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. */
|
/* Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. */
|
||||||
/* This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. */
|
/* This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. */
|
||||||
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
|
MINIZ_EXPORT tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
|
||||||
|
|
||||||
/* Internal/private bits follow. */
|
/* Internal/private bits follow. */
|
||||||
enum
|
enum
|
||||||
@@ -852,14 +937,10 @@ enum
|
|||||||
TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
|
TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
|
|
||||||
mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
|
|
||||||
} tinfl_huff_table;
|
|
||||||
|
|
||||||
#if MINIZ_HAS_64BIT_REGISTERS
|
#if MINIZ_HAS_64BIT_REGISTERS
|
||||||
#define TINFL_USE_64BIT_BITBUF 1
|
#define TINFL_USE_64BIT_BITBUF 1
|
||||||
|
#else
|
||||||
|
#define TINFL_USE_64BIT_BITBUF 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TINFL_USE_64BIT_BITBUF
|
#if TINFL_USE_64BIT_BITBUF
|
||||||
@@ -875,7 +956,13 @@ struct tinfl_decompressor_tag
|
|||||||
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
|
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
|
||||||
tinfl_bit_buf_t m_bit_buf;
|
tinfl_bit_buf_t m_bit_buf;
|
||||||
size_t m_dist_from_out_buf_start;
|
size_t m_dist_from_out_buf_start;
|
||||||
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
|
mz_int16 m_look_up[TINFL_MAX_HUFF_TABLES][TINFL_FAST_LOOKUP_SIZE];
|
||||||
|
mz_int16 m_tree_0[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
|
||||||
|
mz_int16 m_tree_1[TINFL_MAX_HUFF_SYMBOLS_1 * 2];
|
||||||
|
mz_int16 m_tree_2[TINFL_MAX_HUFF_SYMBOLS_2 * 2];
|
||||||
|
mz_uint8 m_code_size_0[TINFL_MAX_HUFF_SYMBOLS_0];
|
||||||
|
mz_uint8 m_code_size_1[TINFL_MAX_HUFF_SYMBOLS_1];
|
||||||
|
mz_uint8 m_code_size_2[TINFL_MAX_HUFF_SYMBOLS_2];
|
||||||
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
|
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -883,6 +970,8 @@ struct tinfl_decompressor_tag
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
@@ -916,10 +1005,6 @@ typedef struct
|
|||||||
mz_uint16 m_bit_flag;
|
mz_uint16 m_bit_flag;
|
||||||
mz_uint16 m_method;
|
mz_uint16 m_method;
|
||||||
|
|
||||||
#ifndef MINIZ_NO_TIME
|
|
||||||
MZ_TIME_T m_time;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* CRC-32 of uncompressed data. */
|
/* CRC-32 of uncompressed data. */
|
||||||
mz_uint32 m_crc32;
|
mz_uint32 m_crc32;
|
||||||
|
|
||||||
@@ -956,6 +1041,11 @@ typedef struct
|
|||||||
/* Guaranteed to be zero terminated, may be truncated to fit. */
|
/* Guaranteed to be zero terminated, may be truncated to fit. */
|
||||||
char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
|
char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
|
||||||
|
|
||||||
|
#ifdef MINIZ_NO_TIME
|
||||||
|
MZ_TIME_T m_padding;
|
||||||
|
#else
|
||||||
|
MZ_TIME_T m_time;
|
||||||
|
#endif
|
||||||
} mz_zip_archive_file_stat;
|
} mz_zip_archive_file_stat;
|
||||||
|
|
||||||
typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
|
typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
|
||||||
@@ -965,29 +1055,29 @@ typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque);
|
|||||||
struct mz_zip_internal_state_tag;
|
struct mz_zip_internal_state_tag;
|
||||||
typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
|
typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
MZ_ZIP_MODE_INVALID = 0,
|
MZ_ZIP_MODE_INVALID = 0,
|
||||||
MZ_ZIP_MODE_READING = 1,
|
MZ_ZIP_MODE_READING = 1,
|
||||||
MZ_ZIP_MODE_WRITING = 2,
|
MZ_ZIP_MODE_WRITING = 2,
|
||||||
MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
|
MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
|
||||||
} mz_zip_mode;
|
} mz_zip_mode;
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
|
MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
|
||||||
MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
|
MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
|
||||||
MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
|
MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
|
||||||
MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800,
|
MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800,
|
||||||
MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG = 0x1000, /* if enabled, mz_zip_reader_locate_file() will be called on each file as its validated to ensure the func finds the file in the central dir (intended for testing) */
|
MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG = 0x1000, /* if enabled, mz_zip_reader_locate_file() will be called on each file as its validated to ensure the func finds the file in the central dir (intended for testing) */
|
||||||
MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = 0x2000, /* validate the local headers, but don't decompress the entire file and check the crc32 */
|
MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = 0x2000, /* validate the local headers, but don't decompress the entire file and check the crc32 */
|
||||||
MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000, /* use the zip64 file format, instead of the original zip file format */
|
MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000, /* always use the zip64 file format, instead of the original zip file format with automatic switch to zip64. Use as flags parameter with mz_zip_writer_init*_v2 */
|
||||||
MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000,
|
MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000,
|
||||||
MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000
|
MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000,
|
||||||
|
/*After adding a compressed file, seek back
|
||||||
|
to local file header and set the correct sizes*/
|
||||||
|
MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000
|
||||||
} mz_zip_flags;
|
} mz_zip_flags;
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
MZ_ZIP_TYPE_INVALID = 0,
|
MZ_ZIP_TYPE_INVALID = 0,
|
||||||
MZ_ZIP_TYPE_USER,
|
MZ_ZIP_TYPE_USER,
|
||||||
MZ_ZIP_TYPE_MEMORY,
|
MZ_ZIP_TYPE_MEMORY,
|
||||||
@@ -998,8 +1088,7 @@ typedef enum
|
|||||||
} mz_zip_type;
|
} mz_zip_type;
|
||||||
|
|
||||||
/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or modify this enum. */
|
/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or modify this enum. */
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
MZ_ZIP_NO_ERROR = 0,
|
MZ_ZIP_NO_ERROR = 0,
|
||||||
MZ_ZIP_UNDEFINED_ERROR,
|
MZ_ZIP_UNDEFINED_ERROR,
|
||||||
MZ_ZIP_TOO_MANY_FILES,
|
MZ_ZIP_TOO_MANY_FILES,
|
||||||
@@ -1055,170 +1144,198 @@ typedef struct
|
|||||||
|
|
||||||
mz_file_read_func m_pRead;
|
mz_file_read_func m_pRead;
|
||||||
mz_file_write_func m_pWrite;
|
mz_file_write_func m_pWrite;
|
||||||
mz_file_needs_keepalive m_pNeeds_keepalive;
|
mz_file_needs_keepalive m_pNeeds_keepalive;
|
||||||
void *m_pIO_opaque;
|
void *m_pIO_opaque;
|
||||||
|
|
||||||
mz_zip_internal_state *m_pState;
|
mz_zip_internal_state *m_pState;
|
||||||
|
|
||||||
} mz_zip_archive;
|
} mz_zip_archive;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
mz_zip_archive *pZip;
|
||||||
|
mz_uint flags;
|
||||||
|
|
||||||
|
int status;
|
||||||
|
|
||||||
|
mz_uint64 read_buf_size, read_buf_ofs, read_buf_avail, comp_remaining, out_buf_ofs, cur_file_ofs;
|
||||||
|
mz_zip_archive_file_stat file_stat;
|
||||||
|
void *pRead_buf;
|
||||||
|
void *pWrite_buf;
|
||||||
|
|
||||||
|
size_t out_blk_remain;
|
||||||
|
|
||||||
|
tinfl_decompressor inflator;
|
||||||
|
|
||||||
|
#ifdef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
|
||||||
|
mz_uint padding;
|
||||||
|
#else
|
||||||
|
mz_uint file_crc32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} mz_zip_reader_extract_iter_state;
|
||||||
|
|
||||||
/* -------- ZIP reading */
|
/* -------- ZIP reading */
|
||||||
|
|
||||||
/* Inits a ZIP archive reader. */
|
/* Inits a ZIP archive reader. */
|
||||||
/* These functions read and validate the archive's central directory. */
|
/* These functions read and validate the archive's central directory. */
|
||||||
mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags);
|
||||||
|
|
||||||
mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags);
|
||||||
|
|
||||||
#ifndef MINIZ_NO_STDIO
|
#ifndef MINIZ_NO_STDIO
|
||||||
/* Read a archive from a disk file. */
|
/* Read a archive from a disk file. */
|
||||||
/* file_start_ofs is the file offset where the archive actually begins, or 0. */
|
/* file_start_ofs is the file offset where the archive actually begins, or 0. */
|
||||||
/* actual_archive_size is the true total size of the archive, which may be smaller than the file's actual size on disk. If zero the entire file is treated as the archive. */
|
/* actual_archive_size is the true total size of the archive, which may be smaller than the file's actual size on disk. If zero the entire file is treated as the archive. */
|
||||||
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
|
||||||
mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size);
|
MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size);
|
||||||
|
|
||||||
/* Read an archive from an already opened FILE, beginning at the current file position. */
|
/* Read an archive from an already opened FILE, beginning at the current file position. */
|
||||||
/* The archive is assumed to be archive_size bytes long. If archive_size is < 0, then the entire rest of the file is assumed to contain the archive. */
|
/* The archive is assumed to be archive_size bytes long. If archive_size is 0, then the entire rest of the file is assumed to contain the archive. */
|
||||||
/* The FILE will NOT be closed when mz_zip_reader_end() is called. */
|
/* The FILE will NOT be closed when mz_zip_reader_end() is called. */
|
||||||
mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. */
|
/* Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. */
|
||||||
mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
|
||||||
|
|
||||||
/* -------- ZIP reading or writing */
|
/* -------- ZIP reading or writing */
|
||||||
|
|
||||||
/* Clears a mz_zip_archive struct to all zeros. */
|
/* Clears a mz_zip_archive struct to all zeros. */
|
||||||
/* Important: This must be done before passing the struct to any mz_zip functions. */
|
/* Important: This must be done before passing the struct to any mz_zip functions. */
|
||||||
void mz_zip_zero_struct(mz_zip_archive *pZip);
|
MINIZ_EXPORT void mz_zip_zero_struct(mz_zip_archive *pZip);
|
||||||
|
|
||||||
mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip);
|
||||||
mz_zip_type mz_zip_get_type(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_zip_type mz_zip_get_type(mz_zip_archive *pZip);
|
||||||
|
|
||||||
/* Returns the total number of files in the archive. */
|
/* Returns the total number of files in the archive. */
|
||||||
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
|
||||||
|
|
||||||
mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip);
|
||||||
mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip);
|
||||||
MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip);
|
MINIZ_EXPORT MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip);
|
||||||
|
|
||||||
/* Reads n bytes of raw archive data, starting at file offset file_ofs, to pBuf. */
|
/* Reads n bytes of raw archive data, starting at file offset file_ofs, to pBuf. */
|
||||||
size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n);
|
MINIZ_EXPORT size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n);
|
||||||
|
|
||||||
/* Attempts to locates a file in the archive's central directory. */
|
|
||||||
/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */
|
|
||||||
/* Returns -1 if the file cannot be found. */
|
|
||||||
int mz_zip_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
|
|
||||||
/* Returns MZ_FALSE if the file cannot be found. */
|
|
||||||
mz_bool mz_zip_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex);
|
|
||||||
|
|
||||||
/* All mz_zip funcs set the m_last_error field in the mz_zip_archive struct. These functions retrieve/manipulate this field. */
|
/* All mz_zip funcs set the m_last_error field in the mz_zip_archive struct. These functions retrieve/manipulate this field. */
|
||||||
/* Note that the m_last_error functionality is not thread safe. */
|
/* Note that the m_last_error functionality is not thread safe. */
|
||||||
mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num);
|
MINIZ_EXPORT mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num);
|
||||||
mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip);
|
||||||
mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip);
|
||||||
mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip);
|
||||||
const char *mz_zip_get_error_string(mz_zip_error mz_err);
|
MINIZ_EXPORT const char *mz_zip_get_error_string(mz_zip_error mz_err);
|
||||||
|
|
||||||
/* MZ_TRUE if the archive file entry is a directory entry. */
|
/* MZ_TRUE if the archive file entry is a directory entry. */
|
||||||
mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
|
MINIZ_EXPORT mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
|
||||||
|
|
||||||
/* MZ_TRUE if the file is encrypted/strong encrypted. */
|
/* MZ_TRUE if the file is encrypted/strong encrypted. */
|
||||||
mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
|
MINIZ_EXPORT mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
|
||||||
|
|
||||||
/* MZ_TRUE if the compression method is supported, and the file is not encrypted, and the file is not a compressed patch file. */
|
/* MZ_TRUE if the compression method is supported, and the file is not encrypted, and the file is not a compressed patch file. */
|
||||||
mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index);
|
MINIZ_EXPORT mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index);
|
||||||
|
|
||||||
/* Retrieves the filename of an archive file entry. */
|
/* Retrieves the filename of an archive file entry. */
|
||||||
/* Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. */
|
/* Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. */
|
||||||
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
|
MINIZ_EXPORT mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
|
||||||
|
|
||||||
/* Attempts to locates a file in the archive's central directory. */
|
/* Attempts to locates a file in the archive's central directory. */
|
||||||
/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */
|
/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */
|
||||||
/* Returns -1 if the file cannot be found. */
|
/* Returns -1 if the file cannot be found. */
|
||||||
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
|
MINIZ_EXPORT int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
|
||||||
int mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *file_index);
|
MINIZ_EXPORT mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *file_index);
|
||||||
|
|
||||||
/* Returns detailed information about an archive file entry. */
|
/* Returns detailed information about an archive file entry. */
|
||||||
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
|
MINIZ_EXPORT mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
|
||||||
|
|
||||||
/* MZ_TRUE if the file is in zip64 format. */
|
/* MZ_TRUE if the file is in zip64 format. */
|
||||||
/* A file is considered zip64 if it contained a zip64 end of central directory marker, or if it contained any zip64 extended file information fields in the central directory. */
|
/* A file is considered zip64 if it contained a zip64 end of central directory marker, or if it contained any zip64 extended file information fields in the central directory. */
|
||||||
mz_bool mz_zip_is_zip64(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_bool mz_zip_is_zip64(mz_zip_archive *pZip);
|
||||||
|
|
||||||
/* Returns the total central directory size in bytes. */
|
/* Returns the total central directory size in bytes. */
|
||||||
/* The current max supported size is <= MZ_UINT32_MAX. */
|
/* The current max supported size is <= MZ_UINT32_MAX. */
|
||||||
size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip);
|
MINIZ_EXPORT size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip);
|
||||||
|
|
||||||
/* Extracts a archive file to a memory buffer using no memory allocation. */
|
/* Extracts a archive file to a memory buffer using no memory allocation. */
|
||||||
/* There must be at least enough room on the stack to store the inflator's state (~34KB or so). */
|
/* There must be at least enough room on the stack to store the inflator's state (~34KB or so). */
|
||||||
mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
|
||||||
mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
|
||||||
|
|
||||||
/* Extracts a archive file to a memory buffer. */
|
/* Extracts a archive file to a memory buffer. */
|
||||||
mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
|
||||||
mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
|
||||||
|
|
||||||
/* Extracts a archive file to a dynamically allocated heap buffer. */
|
/* Extracts a archive file to a dynamically allocated heap buffer. */
|
||||||
/* The memory will be allocated via the mz_zip_archive's alloc/realloc functions. */
|
/* The memory will be allocated via the mz_zip_archive's alloc/realloc functions. */
|
||||||
/* Returns NULL and sets the last error on failure. */
|
/* Returns NULL and sets the last error on failure. */
|
||||||
void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
|
MINIZ_EXPORT void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
|
||||||
void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
|
MINIZ_EXPORT void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
|
||||||
|
|
||||||
/* Extracts a archive file using a callback function to output the file's data. */
|
/* Extracts a archive file using a callback function to output the file's data. */
|
||||||
mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
|
||||||
mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
|
||||||
|
|
||||||
|
/* Extract a file iteratively */
|
||||||
|
MINIZ_EXPORT mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
|
||||||
|
MINIZ_EXPORT mz_zip_reader_extract_iter_state* mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
|
||||||
|
MINIZ_EXPORT size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState, void* pvBuf, size_t buf_size);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state* pState);
|
||||||
|
|
||||||
#ifndef MINIZ_NO_STDIO
|
#ifndef MINIZ_NO_STDIO
|
||||||
/* Extracts a archive file to a disk file and sets its last accessed and modified times. */
|
/* Extracts a archive file to a disk file and sets its last accessed and modified times. */
|
||||||
/* This function only extracts files, not archive directory records. */
|
/* This function only extracts files, not archive directory records. */
|
||||||
mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
|
||||||
mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
|
||||||
|
|
||||||
/* Extracts a archive file starting at the current position in the destination FILE stream. */
|
/* Extracts a archive file starting at the current position in the destination FILE stream. */
|
||||||
mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *File, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *File, mz_uint flags);
|
||||||
mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* TODO */
|
/* TODO */
|
||||||
typedef void *mz_zip_streaming_extract_state_ptr;
|
typedef void *mz_zip_streaming_extract_state_ptr;
|
||||||
mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
|
mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
|
||||||
uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
mz_uint64 mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||||
uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
mz_uint64 mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||||
mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs);
|
mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, mz_uint64 new_ofs);
|
||||||
size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size);
|
size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size);
|
||||||
mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */
|
/* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */
|
||||||
/* It also validates that each file can be successfully uncompressed unless the MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY is specified. */
|
/* It also validates that each file can be successfully uncompressed unless the MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY is specified. */
|
||||||
mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
|
||||||
|
|
||||||
/* Validates an entire archive by calling mz_zip_validate_file() on each file. */
|
/* Validates an entire archive by calling mz_zip_validate_file() on each file. */
|
||||||
mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags);
|
||||||
|
|
||||||
/* Misc utils/helpers, valid for ZIP reading or writing */
|
/* Misc utils/helpers, valid for ZIP reading or writing */
|
||||||
mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr);
|
MINIZ_EXPORT mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr);
|
||||||
mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr);
|
#ifndef MINIZ_NO_STDIO
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Universal end function - calls either mz_zip_reader_end() or mz_zip_writer_end(). */
|
/* Universal end function - calls either mz_zip_reader_end() or mz_zip_writer_end(). */
|
||||||
mz_bool mz_zip_end(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_bool mz_zip_end(mz_zip_archive *pZip);
|
||||||
|
|
||||||
/* -------- ZIP writing */
|
/* -------- ZIP writing */
|
||||||
|
|
||||||
#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
|
#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||||
|
|
||||||
/* Inits a ZIP archive writer. */
|
/* Inits a ZIP archive writer. */
|
||||||
mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
|
/*Set pZip->m_pWrite (and pZip->m_pIO_opaque) before calling mz_zip_writer_init or mz_zip_writer_init_v2*/
|
||||||
mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags);
|
/*The output is streamable, i.e. file_ofs in mz_file_write_func always increases only by n*/
|
||||||
mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
|
MINIZ_EXPORT mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
|
||||||
mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags);
|
||||||
|
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags);
|
||||||
|
|
||||||
#ifndef MINIZ_NO_STDIO
|
#ifndef MINIZ_NO_STDIO
|
||||||
mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
|
||||||
mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags);
|
||||||
mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. */
|
/* Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. */
|
||||||
@@ -1227,50 +1344,57 @@ mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint f
|
|||||||
/* Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. */
|
/* Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. */
|
||||||
/* Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before */
|
/* Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before */
|
||||||
/* the archive is finalized the file's central directory will be hosed. */
|
/* the archive is finalized the file's central directory will be hosed. */
|
||||||
mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
|
||||||
mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
|
||||||
|
|
||||||
/* Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. */
|
/* Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. */
|
||||||
/* To add a directory entry, call this method with an archive name ending in a forwardslash with an empty buffer. */
|
/* To add a directory entry, call this method with an archive name ending in a forwardslash with an empty buffer. */
|
||||||
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
|
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
|
||||||
mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
|
||||||
|
|
||||||
/* Like mz_zip_writer_add_mem(), except you can specify a file comment field, and optionally supply the function with already compressed data. */
|
/* Like mz_zip_writer_add_mem(), except you can specify a file comment field, and optionally supply the function with already compressed data. */
|
||||||
/* uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA flag is specified. */
|
/* uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA flag is specified. */
|
||||||
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
|
||||||
mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
|
mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
|
||||||
|
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
|
||||||
|
mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
|
||||||
|
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
|
||||||
|
|
||||||
|
/* Adds the contents of a file to an archive. This function also records the disk file's modified time into the archive. */
|
||||||
|
/* File data is supplied via a read callback function. User mz_zip_writer_add_(c)file to add a file directly.*/
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size,
|
||||||
|
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
|
||||||
|
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
|
||||||
|
|
||||||
mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
|
|
||||||
mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
|
|
||||||
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
|
|
||||||
|
|
||||||
#ifndef MINIZ_NO_STDIO
|
#ifndef MINIZ_NO_STDIO
|
||||||
/* Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. */
|
/* Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. */
|
||||||
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
|
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
|
||||||
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
||||||
|
|
||||||
/* Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. */
|
/* Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. */
|
||||||
mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add,
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size,
|
||||||
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
|
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
|
||||||
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
|
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Adds a file to an archive by fully cloning the data from another archive. */
|
/* Adds a file to an archive by fully cloning the data from another archive. */
|
||||||
/* This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data (it may add or modify the zip64 local header extra data field), and the optional descriptor following the compressed data. */
|
/* This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data (it may add or modify the zip64 local header extra data field), and the optional descriptor following the compressed data. */
|
||||||
mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index);
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index);
|
||||||
|
|
||||||
/* Finalizes the archive by writing the central directory records followed by the end of central directory record. */
|
/* Finalizes the archive by writing the central directory records followed by the end of central directory record. */
|
||||||
/* After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). */
|
/* After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). */
|
||||||
/* An archive must be manually finalized by calling this function for it to be valid. */
|
/* An archive must be manually finalized by calling this function for it to be valid. */
|
||||||
mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
|
||||||
|
|
||||||
/* Finalizes a heap archive, returning a poiner to the heap block and its size. */
|
/* Finalizes a heap archive, returning a pointer to the heap block and its size. */
|
||||||
/* The heap block will be allocated using the mz_zip_archive's alloc/realloc callbacks. */
|
/* The heap block will be allocated using the mz_zip_archive's alloc/realloc callbacks. */
|
||||||
mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize);
|
MINIZ_EXPORT mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize);
|
||||||
|
|
||||||
/* Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. */
|
/* Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. */
|
||||||
/* Note for the archive to be valid, it *must* have been finalized before ending (this function will not do it for you). */
|
/* Note for the archive to be valid, it *must* have been finalized before ending (this function will not do it for you). */
|
||||||
mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
|
MINIZ_EXPORT mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
|
||||||
|
|
||||||
/* -------- Misc. high-level helper functions: */
|
/* -------- Misc. high-level helper functions: */
|
||||||
|
|
||||||
@@ -1278,14 +1402,16 @@ mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
|
|||||||
/* Note this is NOT a fully safe operation. If it crashes or dies in some way your archive can be left in a screwed up state (without a central directory). */
|
/* Note this is NOT a fully safe operation. If it crashes or dies in some way your archive can be left in a screwed up state (without a central directory). */
|
||||||
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
|
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
|
||||||
/* TODO: Perhaps add an option to leave the existing central dir in place in case the add dies? We could then truncate the file (so the old central dir would be at the end) if something goes wrong. */
|
/* TODO: Perhaps add an option to leave the existing central dir in place in case the add dies? We could then truncate the file (so the old central dir would be at the end) if something goes wrong. */
|
||||||
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
||||||
mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr);
|
MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr);
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_STDIO
|
||||||
/* Reads a single file from an archive into a heap block. */
|
/* Reads a single file from an archive into a heap block. */
|
||||||
/* If pComment is not NULL, only the file with the specified comment will be extracted. */
|
/* If pComment is not NULL, only the file with the specified comment will be extracted. */
|
||||||
/* Returns NULL on failure. */
|
/* Returns NULL on failure. */
|
||||||
void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags);
|
MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags);
|
||||||
void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr);
|
MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */
|
#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */
|
||||||
|
|
||||||
11
Source/ThirdParty/tinyexr/tinyexr.Build.cs
vendored
11
Source/ThirdParty/tinyexr/tinyexr.Build.cs
vendored
@@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
using Flax.Build;
|
using Flax.Build;
|
||||||
using Flax.Build.NativeCpp;
|
using Flax.Build.NativeCpp;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// https://github.com/syoyo/tinyexr
|
/// https://github.com/syoyo/tinyexr
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class tinyexr : HeaderOnlyModule
|
public class tinyexr : ThirdPartyModule
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Init()
|
public override void Init()
|
||||||
@@ -19,4 +20,12 @@ public class tinyexr : HeaderOnlyModule
|
|||||||
// Merge third-party modules into engine binary
|
// Merge third-party modules into engine binary
|
||||||
BinaryModuleName = "FlaxEngine";
|
BinaryModuleName = "FlaxEngine";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Setup(BuildOptions options)
|
||||||
|
{
|
||||||
|
base.Setup(options);
|
||||||
|
|
||||||
|
options.PublicIncludePaths.Add(Path.Combine(Globals.EngineRoot, "Source/ThirdParty/tinyexr"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
Source/ThirdParty/tinyexr/tinyexr.h
vendored
7
Source/ThirdParty/tinyexr/tinyexr.h
vendored
@@ -659,7 +659,7 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TINYEXR_USE_MINIZ) && (TINYEXR_USE_MINIZ==1)
|
#if defined(TINYEXR_USE_MINIZ) && (TINYEXR_USE_MINIZ==1)
|
||||||
#include <ThirdParty/OpenFBX/miniz.h>
|
#include <miniz.h>
|
||||||
#else
|
#else
|
||||||
// Issue #46. Please include your own zlib-compatible API header before
|
// Issue #46. Please include your own zlib-compatible API header before
|
||||||
// including `tinyexr.h`
|
// including `tinyexr.h`
|
||||||
@@ -4923,7 +4923,7 @@ static int DecodeTiledLevel(EXRImage* exr_image, const EXRHeader* exr_header,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
exr_image->tiles = static_cast<EXRTile*>(
|
exr_image->tiles = static_cast<EXRTile*>(
|
||||||
calloc(sizeof(EXRTile), static_cast<size_t>(num_tiles)));
|
calloc(static_cast<size_t>(num_tiles), sizeof(EXRTile)));
|
||||||
|
|
||||||
#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
|
#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
|
||||||
std::vector<std::thread> workers;
|
std::vector<std::thread> workers;
|
||||||
@@ -9287,9 +9287,6 @@ int SaveEXR(const float *data, int width, int height, int components,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ret = SaveEXRImageToFile(&image, &header, outfilename, err);
|
int ret = SaveEXRImageToFile(&image, &header, outfilename, err);
|
||||||
if (ret != TINYEXR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(header.channels);
|
free(header.channels);
|
||||||
free(header.pixel_types);
|
free(header.pixel_types);
|
||||||
|
|||||||
Reference in New Issue
Block a user