Fix X-Importer decompress algorithm
parent
27bcddfb1a
commit
23b43d1825
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -60,26 +58,11 @@ using namespace Assimp::Formatter;
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
|
||||||
|
|
||||||
/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
|
||||||
#include <zlib.h>
|
|
||||||
#else
|
|
||||||
#include "../contrib/zlib/zlib.h"
|
|
||||||
#endif*/
|
|
||||||
#include "Common/Compression.h"
|
#include "Common/Compression.h"
|
||||||
|
|
||||||
// Magic identifier for MSZIP compressed data
|
// Magic identifier for MSZIP compressed data
|
||||||
#define MSZIP_MAGIC 0x4B43
|
constexpr unsigned int MSZIP_MAGIC = 0x4B43;
|
||||||
#define MSZIP_BLOCK 32786
|
constexpr size_t MSZIP_BLOCK = 32786l;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Dummy memory wrappers for use with zlib
|
|
||||||
/* static void *dummy_alloc(void * opaque, unsigned int items, unsigned int size) {
|
|
||||||
return ::operator new(items *size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dummy_free(void * opaque, void *address) {
|
|
||||||
return ::operator delete(address);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
|
#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
|
||||||
|
|
||||||
|
@ -172,17 +155,6 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
|
||||||
* ///////////////////////////////////////////////////////////////////////
|
* ///////////////////////////////////////////////////////////////////////
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Compression compression;
|
|
||||||
// build a zlib stream
|
|
||||||
/* z_stream stream;
|
|
||||||
stream.opaque = nullptr;
|
|
||||||
stream.zalloc = &dummy_alloc;
|
|
||||||
stream.zfree = &dummy_free;
|
|
||||||
stream.data_type = (mIsBinaryFormat ? Z_BINARY : Z_ASCII);
|
|
||||||
|
|
||||||
// initialize the inflation algorithm
|
|
||||||
::inflateInit2(&stream, -MAX_WBITS);*/
|
|
||||||
|
|
||||||
// skip unknown data (checksum, flags?)
|
// skip unknown data (checksum, flags?)
|
||||||
mP += 6;
|
mP += 6;
|
||||||
|
|
||||||
|
@ -213,43 +185,23 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate storage and terminating zero and do the actual uncompressing
|
// Allocate storage and terminating zero and do the actual uncompressing
|
||||||
|
Compression compression;
|
||||||
uncompressed.resize(est_out + 1);
|
uncompressed.resize(est_out + 1);
|
||||||
char *out = &uncompressed.front();
|
char *out = &uncompressed.front();
|
||||||
|
|
||||||
if (compression.open(mIsBinaryFormat ? Compression::Format::Binary : Compression::Format::ASCII)) {
|
if (compression.open(mIsBinaryFormat ? Compression::Format::Binary : Compression::Format::ASCII)) {
|
||||||
compression.decompress(mP, std::distance(mP, mEnd-3), uncompressed);
|
while (mP + 3 < mEnd) {
|
||||||
|
uint16_t ofs = *((uint16_t *)mP);
|
||||||
|
AI_SWAP2(ofs);
|
||||||
|
mP += 4;
|
||||||
|
|
||||||
|
if (mP + ofs > mEnd + 2) {
|
||||||
|
throw DeadlyImportError("X: Unexpected EOF in compressed chunk");
|
||||||
|
}
|
||||||
|
out += compression.decompressBlock(mP, ofs, out, MSZIP_BLOCK);
|
||||||
|
mP += ofs;
|
||||||
|
}
|
||||||
compression.close();
|
compression.close();
|
||||||
}
|
}
|
||||||
/* while (mP + 3 < mEnd) {
|
|
||||||
uint16_t ofs = *((uint16_t *)mP);
|
|
||||||
AI_SWAP2(ofs);
|
|
||||||
mP += 4;
|
|
||||||
|
|
||||||
if (mP + ofs > mEnd + 2) {
|
|
||||||
throw DeadlyImportError("X: Unexpected EOF in compressed chunk");
|
|
||||||
}
|
|
||||||
|
|
||||||
// push data to the stream
|
|
||||||
stream.next_in = (Bytef *)mP;
|
|
||||||
stream.avail_in = ofs;
|
|
||||||
stream.next_out = (Bytef *)out;
|
|
||||||
stream.avail_out = MSZIP_BLOCK;
|
|
||||||
|
|
||||||
// and decompress the data ....
|
|
||||||
int ret = ::inflate(&stream, Z_SYNC_FLUSH);
|
|
||||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
|
||||||
throw DeadlyImportError("X: Failed to decompress MSZIP-compressed data");
|
|
||||||
|
|
||||||
::inflateReset(&stream);
|
|
||||||
::inflateSetDictionary(&stream, (const Bytef *)out, MSZIP_BLOCK - stream.avail_out);
|
|
||||||
|
|
||||||
// and advance to the next offset
|
|
||||||
out += MSZIP_BLOCK - stream.avail_out;
|
|
||||||
mP += ofs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// terminate zlib
|
|
||||||
::inflateEnd(&stream);*/
|
|
||||||
|
|
||||||
// ok, update pointers to point to the uncompressed file data
|
// ok, update pointers to point to the uncompressed file data
|
||||||
mP = &uncompressed[0];
|
mP = &uncompressed[0];
|
||||||
|
@ -507,7 +459,7 @@ void XFileParser::ParseDataObjectSkinWeights(Mesh *pMesh) {
|
||||||
bone.mWeights.reserve(numWeights);
|
bone.mWeights.reserve(numWeights);
|
||||||
|
|
||||||
for (unsigned int a = 0; a < numWeights; a++) {
|
for (unsigned int a = 0; a < numWeights; a++) {
|
||||||
BoneWeight weight;
|
BoneWeight weight = {};
|
||||||
weight.mVertex = ReadInt();
|
weight.mVertex = ReadInt();
|
||||||
bone.mWeights.push_back(weight);
|
bone.mWeights.push_back(weight);
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,7 @@ size_t Compression::decompress(const void *data, size_t in, std::vector<char> &u
|
||||||
do {
|
do {
|
||||||
mImpl->mZSstream.avail_out = MYBLOCK;
|
mImpl->mZSstream.avail_out = MYBLOCK;
|
||||||
mImpl->mZSstream.next_out = block;
|
mImpl->mZSstream.next_out = block;
|
||||||
|
|
||||||
ret = inflate(&mImpl->mZSstream, Z_NO_FLUSH);
|
ret = inflate(&mImpl->mZSstream, Z_NO_FLUSH);
|
||||||
|
|
||||||
if (ret != Z_STREAM_END && ret != Z_OK) {
|
if (ret != Z_STREAM_END && ret != Z_OK) {
|
||||||
|
@ -123,6 +124,30 @@ size_t Compression::decompress(const void *data, size_t in, std::vector<char> &u
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Compression::decompressBlock(const void *data, size_t in, char *out, size_t availableOut) {
|
||||||
|
|
||||||
|
// push data to the stream
|
||||||
|
mImpl->mZSstream.next_in = (Bytef *)data;
|
||||||
|
mImpl->mZSstream.avail_in = (uInt)in;
|
||||||
|
mImpl->mZSstream.next_out = (Bytef *)out;
|
||||||
|
mImpl->mZSstream.avail_out = (uInt)availableOut;
|
||||||
|
|
||||||
|
// and decompress the data ....
|
||||||
|
int ret = ::inflate(&mImpl->mZSstream, Z_SYNC_FLUSH);
|
||||||
|
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||||
|
throw DeadlyImportError("X: Failed to decompress MSZIP-compressed data");
|
||||||
|
|
||||||
|
::inflateReset(&mImpl->mZSstream);
|
||||||
|
::inflateSetDictionary(&mImpl->mZSstream, (const Bytef *)out, (uInt)availableOut - mImpl->mZSstream.avail_out);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
::inflateReset(&mImpl->mZSstream);
|
||||||
|
::inflateSetDictionary(&mImpl->mZSstream, (const Bytef *)out, (uInt)availableOut - mImpl->mZSstream.avail_out);
|
||||||
|
|
||||||
|
return availableOut - (size_t)mImpl->mZSstream.avail_out;
|
||||||
|
}
|
||||||
|
|
||||||
bool Compression::isOpen() const {
|
bool Compression::isOpen() const {
|
||||||
ai_assert(mImpl != nullptr);
|
ai_assert(mImpl != nullptr);
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ public:
|
||||||
/// @param[out uncompressed A std::vector containing the decompressed data.
|
/// @param[out uncompressed A std::vector containing the decompressed data.
|
||||||
size_t decompress(const void *data, size_t in, std::vector<char> &uncompressed);
|
size_t decompress(const void *data, size_t in, std::vector<char> &uncompressed);
|
||||||
|
|
||||||
|
size_t decompressBlock(const void *data, size_t in, char *out, size_t availableOut);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct impl;
|
struct impl;
|
||||||
impl *mImpl;
|
impl *mImpl;
|
||||||
|
|
Loading…
Reference in New Issue