Migrate more importers to compression class
parent
eb5a7938e0
commit
27bcddfb1a
|
@ -66,11 +66,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// zlib is needed for compressed blend files
|
// zlib is needed for compressed blend files
|
||||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||||
# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
#include "Common/Compression.h"
|
||||||
|
/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||||
# include <zlib.h>
|
# include <zlib.h>
|
||||||
# else
|
# else
|
||||||
# include "../contrib/zlib/zlib.h"
|
# include "../contrib/zlib/zlib.h"
|
||||||
# endif
|
# endif*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
@ -141,7 +142,7 @@ void BlenderImporter::SetupProperties(const Importer * /*pImp*/) {
|
||||||
void BlenderImporter::InternReadFile(const std::string &pFile,
|
void BlenderImporter::InternReadFile(const std::string &pFile,
|
||||||
aiScene *pScene, IOSystem *pIOHandler) {
|
aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||||
std::vector<Bytef> uncompressed;
|
std::vector<char> uncompressed;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FileDatabase file;
|
FileDatabase file;
|
||||||
|
@ -159,7 +160,6 @@ void BlenderImporter::InternReadFile(const std::string &pFile,
|
||||||
#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||||
ThrowException("BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?");
|
ThrowException("BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?");
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
|
if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
|
||||||
ThrowException("BLENDER magic bytes are missing, couldn't find GZIP header either");
|
ThrowException("BLENDER magic bytes are missing, couldn't find GZIP header either");
|
||||||
}
|
}
|
||||||
|
@ -173,42 +173,12 @@ void BlenderImporter::InternReadFile(const std::string &pFile,
|
||||||
stream->Seek(0L, aiOrigin_SET);
|
stream->Seek(0L, aiOrigin_SET);
|
||||||
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
|
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
|
||||||
|
|
||||||
// build a zlib stream
|
size_t total = 0;
|
||||||
z_stream zstream;
|
Compression compression;
|
||||||
zstream.opaque = Z_NULL;
|
if (compression.open(Compression::Format::Binary)) {
|
||||||
zstream.zalloc = Z_NULL;
|
total = compression.decompress((unsigned char *)reader->GetPtr(), reader->GetRemainingSize(), uncompressed);
|
||||||
zstream.zfree = Z_NULL;
|
compression.close();
|
||||||
zstream.data_type = Z_BINARY;
|
}
|
||||||
|
|
||||||
// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
|
|
||||||
inflateInit2(&zstream, 16 + MAX_WBITS);
|
|
||||||
|
|
||||||
zstream.next_in = reinterpret_cast<Bytef *>(reader->GetPtr());
|
|
||||||
zstream.avail_in = (uInt)reader->GetRemainingSize();
|
|
||||||
|
|
||||||
size_t total = 0l;
|
|
||||||
|
|
||||||
// TODO: be smarter about this, decompress directly into heap buffer
|
|
||||||
// and decompress the data .... do 1k chunks in the hope that we won't kill the stack
|
|
||||||
#define MYBLOCK 1024
|
|
||||||
Bytef block[MYBLOCK];
|
|
||||||
int ret;
|
|
||||||
do {
|
|
||||||
zstream.avail_out = MYBLOCK;
|
|
||||||
zstream.next_out = block;
|
|
||||||
ret = inflate(&zstream, Z_NO_FLUSH);
|
|
||||||
|
|
||||||
if (ret != Z_STREAM_END && ret != Z_OK) {
|
|
||||||
ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .BLEND file");
|
|
||||||
}
|
|
||||||
const size_t have = MYBLOCK - zstream.avail_out;
|
|
||||||
total += have;
|
|
||||||
uncompressed.resize(total);
|
|
||||||
memcpy(uncompressed.data() + total - have, block, have);
|
|
||||||
} while (ret != Z_STREAM_END);
|
|
||||||
|
|
||||||
// terminate zlib
|
|
||||||
inflateEnd(&zstream);
|
|
||||||
|
|
||||||
// replace the input stream with a memory stream
|
// replace the input stream with a memory stream
|
||||||
stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total));
|
stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total));
|
||||||
|
|
|
@ -46,11 +46,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
//#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||||
# include <zlib.h>
|
#include "Common/Compression.h"
|
||||||
|
/*# include <zlib.h>
|
||||||
#else
|
#else
|
||||||
# include "../contrib/zlib/zlib.h"
|
# include "../contrib/zlib/zlib.h"
|
||||||
#endif
|
#endif*/
|
||||||
|
|
||||||
#include "FBXTokenizer.h"
|
#include "FBXTokenizer.h"
|
||||||
#include "FBXParser.h"
|
#include "FBXParser.h"
|
||||||
|
@ -571,8 +572,11 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
|
||||||
else if(encmode == 1) {
|
else if(encmode == 1) {
|
||||||
// zlib/deflate, next comes ZIP head (0x78 0x01)
|
// zlib/deflate, next comes ZIP head (0x78 0x01)
|
||||||
// see http://www.ietf.org/rfc/rfc1950.txt
|
// see http://www.ietf.org/rfc/rfc1950.txt
|
||||||
|
Compression compress;
|
||||||
z_stream zstream;
|
if (compress.open(Compression::Format::Binary)) {
|
||||||
|
compress.decompress(data, comp_len, buff);
|
||||||
|
}
|
||||||
|
/* z_stream zstream;
|
||||||
zstream.opaque = Z_NULL;
|
zstream.opaque = Z_NULL;
|
||||||
zstream.zalloc = Z_NULL;
|
zstream.zalloc = Z_NULL;
|
||||||
zstream.zfree = Z_NULL;
|
zstream.zfree = Z_NULL;
|
||||||
|
@ -581,9 +585,9 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
|
||||||
// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
|
// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
|
||||||
if(Z_OK != inflateInit(&zstream)) {
|
if(Z_OK != inflateInit(&zstream)) {
|
||||||
ParseError("failure initializing zlib");
|
ParseError("failure initializing zlib");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
zstream.next_in = reinterpret_cast<Bytef*>( const_cast<char*>(data) );
|
/* zstream.next_in = reinterpret_cast<Bytef *>(const_cast<char *>(data));
|
||||||
zstream.avail_in = comp_len;
|
zstream.avail_in = comp_len;
|
||||||
|
|
||||||
zstream.avail_out = static_cast<uInt>(buff.size());
|
zstream.avail_out = static_cast<uInt>(buff.size());
|
||||||
|
@ -595,7 +599,7 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
|
||||||
}
|
}
|
||||||
|
|
||||||
// terminate zlib
|
// terminate zlib
|
||||||
inflateEnd(&zstream);
|
inflateEnd(&zstream);*/
|
||||||
}
|
}
|
||||||
#ifdef ASSIMP_BUILD_DEBUG
|
#ifdef ASSIMP_BUILD_DEBUG
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -60,11 +60,12 @@ using namespace Assimp::Formatter;
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#else
|
#else
|
||||||
#include "../contrib/zlib/zlib.h"
|
#include "../contrib/zlib/zlib.h"
|
||||||
#endif
|
#endif*/
|
||||||
|
#include "Common/Compression.h"
|
||||||
|
|
||||||
// Magic identifier for MSZIP compressed data
|
// Magic identifier for MSZIP compressed data
|
||||||
#define MSZIP_MAGIC 0x4B43
|
#define MSZIP_MAGIC 0x4B43
|
||||||
|
@ -72,13 +73,13 @@ using namespace Assimp::Formatter;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Dummy memory wrappers for use with zlib
|
// Dummy memory wrappers for use with zlib
|
||||||
static void *dummy_alloc(void * /*opaque*/, unsigned int items, unsigned int size) {
|
/* static void *dummy_alloc(void * opaque, unsigned int items, unsigned int size) {
|
||||||
return ::operator new(items *size);
|
return ::operator new(items *size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dummy_free(void * /*opaque*/, void *address) {
|
static void dummy_free(void * opaque, void *address) {
|
||||||
return ::operator delete(address);
|
return ::operator delete(address);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
|
#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
|
||||||
|
|
||||||
|
@ -171,15 +172,16 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
|
||||||
* ///////////////////////////////////////////////////////////////////////
|
* ///////////////////////////////////////////////////////////////////////
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Compression compression;
|
||||||
// build a zlib stream
|
// build a zlib stream
|
||||||
z_stream stream;
|
/* z_stream stream;
|
||||||
stream.opaque = nullptr;
|
stream.opaque = nullptr;
|
||||||
stream.zalloc = &dummy_alloc;
|
stream.zalloc = &dummy_alloc;
|
||||||
stream.zfree = &dummy_free;
|
stream.zfree = &dummy_free;
|
||||||
stream.data_type = (mIsBinaryFormat ? Z_BINARY : Z_ASCII);
|
stream.data_type = (mIsBinaryFormat ? Z_BINARY : Z_ASCII);
|
||||||
|
|
||||||
// initialize the inflation algorithm
|
// initialize the inflation algorithm
|
||||||
::inflateInit2(&stream, -MAX_WBITS);
|
::inflateInit2(&stream, -MAX_WBITS);*/
|
||||||
|
|
||||||
// skip unknown data (checksum, flags?)
|
// skip unknown data (checksum, flags?)
|
||||||
mP += 6;
|
mP += 6;
|
||||||
|
@ -213,7 +215,12 @@ 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
|
||||||
uncompressed.resize(est_out + 1);
|
uncompressed.resize(est_out + 1);
|
||||||
char *out = &uncompressed.front();
|
char *out = &uncompressed.front();
|
||||||
while (mP + 3 < mEnd) {
|
|
||||||
|
if (compression.open(mIsBinaryFormat ? Compression::Format::Binary : Compression::Format::ASCII)) {
|
||||||
|
compression.decompress(mP, std::distance(mP, mEnd-3), uncompressed);
|
||||||
|
compression.close();
|
||||||
|
}
|
||||||
|
/* while (mP + 3 < mEnd) {
|
||||||
uint16_t ofs = *((uint16_t *)mP);
|
uint16_t ofs = *((uint16_t *)mP);
|
||||||
AI_SWAP2(ofs);
|
AI_SWAP2(ofs);
|
||||||
mP += 4;
|
mP += 4;
|
||||||
|
@ -242,7 +249,7 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
|
||||||
}
|
}
|
||||||
|
|
||||||
// terminate zlib
|
// terminate zlib
|
||||||
::inflateEnd(&stream);
|
::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];
|
||||||
|
|
|
@ -112,7 +112,7 @@ const aiImporterDesc *XGLImporter::GetInfo() const {
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
|
||||||
std::vector<unsigned char> uncompressed;
|
std::vector<char> uncompressed;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_scene = pScene;
|
m_scene = pScene;
|
||||||
|
@ -132,7 +132,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
|
|
||||||
Compression c;
|
Compression c;
|
||||||
size_t total = 0l;
|
size_t total = 0l;
|
||||||
if (c.open()) {
|
if (c.open(Compression::Format::Binary)) {
|
||||||
// skip two extra bytes, zgl files do carry a crc16 upfront (I think)
|
// skip two extra bytes, zgl files do carry a crc16 upfront (I think)
|
||||||
raw_reader->IncPtr(2);
|
raw_reader->IncPtr(2);
|
||||||
total = c.decompress((unsigned char *)raw_reader->GetPtr(), raw_reader->GetRemainingSize(), uncompressed);
|
total = c.decompress((unsigned char *)raw_reader->GetPtr(), raw_reader->GetRemainingSize(), uncompressed);
|
||||||
|
|
|
@ -70,7 +70,7 @@ Compression::~Compression() {
|
||||||
delete mImpl;
|
delete mImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compression::open() {
|
bool Compression::open(Format format) {
|
||||||
ai_assert(mImpl != nullptr);
|
ai_assert(mImpl != nullptr);
|
||||||
|
|
||||||
if (mImpl->mOpen) {
|
if (mImpl->mOpen) {
|
||||||
|
@ -81,7 +81,11 @@ bool Compression::open() {
|
||||||
mImpl->mZSstream.opaque = Z_NULL;
|
mImpl->mZSstream.opaque = Z_NULL;
|
||||||
mImpl->mZSstream.zalloc = Z_NULL;
|
mImpl->mZSstream.zalloc = Z_NULL;
|
||||||
mImpl->mZSstream.zfree = Z_NULL;
|
mImpl->mZSstream.zfree = Z_NULL;
|
||||||
mImpl->mZSstream.data_type = Z_BINARY;
|
if (format == Format::Binary) {
|
||||||
|
mImpl->mZSstream.data_type = Z_BINARY;
|
||||||
|
} else {
|
||||||
|
mImpl->mZSstream.data_type = Z_ASCII;
|
||||||
|
}
|
||||||
|
|
||||||
// raw decompression without a zlib or gzip header
|
// raw decompression without a zlib or gzip header
|
||||||
inflateInit2(&mImpl->mZSstream, -MAX_WBITS);
|
inflateInit2(&mImpl->mZSstream, -MAX_WBITS);
|
||||||
|
@ -90,12 +94,12 @@ bool Compression::open() {
|
||||||
return mImpl->mOpen;
|
return mImpl->mOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr size_t MYBLOCK = 1024;
|
constexpr size_t MYBLOCK = 32786;
|
||||||
|
|
||||||
size_t Compression::decompress(unsigned char *data, size_t in, std::vector<unsigned char> &uncompressed) {
|
size_t Compression::decompress(const void *data, size_t in, std::vector<char> &uncompressed) {
|
||||||
ai_assert(mImpl != nullptr);
|
ai_assert(mImpl != nullptr);
|
||||||
|
|
||||||
mImpl->mZSstream.next_in = reinterpret_cast<Bytef *>(data);
|
mImpl->mZSstream.next_in = (Bytef*)(data);
|
||||||
mImpl->mZSstream.avail_in = (uInt)in;
|
mImpl->mZSstream.avail_in = (uInt)in;
|
||||||
|
|
||||||
Bytef block[MYBLOCK] = {};
|
Bytef block[MYBLOCK] = {};
|
||||||
|
|
|
@ -48,6 +48,13 @@ namespace Assimp {
|
||||||
/// @brief This class provides the decompression of zlib-compressed data.
|
/// @brief This class provides the decompression of zlib-compressed data.
|
||||||
class Compression {
|
class Compression {
|
||||||
public:
|
public:
|
||||||
|
enum class Format {
|
||||||
|
Binary = 0,
|
||||||
|
ASCII,
|
||||||
|
|
||||||
|
NumFormats,
|
||||||
|
InvalidFormat
|
||||||
|
};
|
||||||
/// @brief The class constructor.
|
/// @brief The class constructor.
|
||||||
Compression();
|
Compression();
|
||||||
|
|
||||||
|
@ -56,7 +63,7 @@ public:
|
||||||
|
|
||||||
/// @brief Will open the access to the compression.
|
/// @brief Will open the access to the compression.
|
||||||
/// @return true if close was successful, false if not.
|
/// @return true if close was successful, false if not.
|
||||||
bool open();
|
bool open(Format format);
|
||||||
|
|
||||||
/// @brief Will return the open state.
|
/// @brief Will return the open state.
|
||||||
/// @return true if the access is opened, false if not.
|
/// @return true if the access is opened, false if not.
|
||||||
|
@ -70,7 +77,7 @@ public:
|
||||||
/// @param[in] data The data to decompress
|
/// @param[in] data The data to decompress
|
||||||
/// @param[in] in The size of the data.
|
/// @param[in] in The size of the data.
|
||||||
/// @param[out uncompressed A std::vector containing the decompressed data.
|
/// @param[out uncompressed A std::vector containing the decompressed data.
|
||||||
size_t decompress(unsigned char *data, size_t in, std::vector<unsigned char> &uncompressed);
|
size_t decompress(const void *data, size_t in, std::vector<char> &uncompressed);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct impl;
|
struct impl;
|
||||||
|
|
Loading…
Reference in New Issue