Rework format + introdule missing C++11 features

pull/4072/head
Kim Kulling 2021-09-08 23:18:13 +02:00
parent be0ab89afe
commit f47479aba4
22 changed files with 258 additions and 252 deletions

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -54,33 +52,36 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
void Bitmap::Save(aiTexture *texture, IOStream *file) { bool Bitmap::Save(aiTexture *texture, IOStream *file) {
if (file != nullptr) { if (file == nullptr) {
Header header; return false;
DIB dib;
dib.size = DIB::dib_size;
dib.width = texture->mWidth;
dib.height = texture->mHeight;
dib.planes = 1;
dib.bits_per_pixel = 8 * mBytesPerPixel;
dib.compression = 0;
dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height;
dib.x_resolution = 0;
dib.y_resolution = 0;
dib.nb_colors = 0;
dib.nb_important_colors = 0;
header.type = 0x4D42; // 'BM'
header.offset = Header::header_size + DIB::dib_size;
header.size = header.offset + dib.image_size;
header.reserved1 = 0;
header.reserved2 = 0;
WriteHeader(header, file);
WriteDIB(dib, file);
WriteData(texture, file);
} }
Header header;
DIB dib;
dib.size = DIB::dib_size;
dib.width = texture->mWidth;
dib.height = texture->mHeight;
dib.planes = 1;
dib.bits_per_pixel = 8 * mBytesPerPixel;
dib.compression = 0;
dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height;
dib.x_resolution = 0;
dib.y_resolution = 0;
dib.nb_colors = 0;
dib.nb_important_colors = 0;
header.type = 0x4D42; // 'BM'
header.offset = Header::header_size + DIB::dib_size;
header.size = header.offset + dib.image_size;
header.reserved1 = 0;
header.reserved2 = 0;
WriteHeader(header, file);
WriteDIB(dib, file);
WriteData(texture, file);
return true;
} }
template <typename T> template <typename T>

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -55,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
#include "defs.h" #include "defs.h"
#include <stdint.h> #include <cstdint>
#include <cstddef> #include <cstddef>
struct aiTexture; struct aiTexture;
@ -64,6 +62,10 @@ namespace Assimp {
class IOStream; class IOStream;
// ---------------------------------------------------------------------------
/**
* This class is used to store and write bitmap information.
*/
class ASSIMP_API Bitmap { class ASSIMP_API Bitmap {
protected: protected:
@ -114,7 +116,11 @@ protected:
static constexpr std::size_t mBytesPerPixel = 4; static constexpr std::size_t mBytesPerPixel = 4;
public: public:
static void Save(aiTexture* texture, IOStream* file); /// @brief Will save an aiTexture instance as a bitmap.
/// @param texture The pointer to the texture instance
/// @param file The filename to save into.
/// @return true if successfully saved, false if not.
static bool Save(aiTexture* texture, IOStream* file);
protected: protected:
static void WriteHeader(Header& header, IOStream* file); static void WriteHeader(Header& header, IOStream* file);

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -44,14 +42,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Provides cheat implementations for IOSystem and IOStream to /** @file Provides cheat implementations for IOSystem and IOStream to
* redirect exporter output to a blob chain.*/ * redirect exporter output to a blob chain.*/
#pragma once
#ifndef AI_BLOBIOSYSTEM_H_INCLUDED #ifndef AI_BLOBIOSYSTEM_H_INCLUDED
#define AI_BLOBIOSYSTEM_H_INCLUDED #define AI_BLOBIOSYSTEM_H_INCLUDED
#include <assimp/cexport.h> #include <assimp/cexport.h>
#include <stdint.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <cstdint>
#include <set> #include <set>
#include <vector> #include <vector>
@ -63,6 +62,10 @@ class BlobIOSystem;
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
class BlobIOStream : public IOStream { class BlobIOStream : public IOStream {
public: public:
/// @brief The class constructor with all needed parameters
/// @param creator Pointer to the creator instance
/// @param file The filename
/// @param initial The initial size
BlobIOStream(BlobIOSystem *creator, const std::string &file, size_t initial = 4096) : BlobIOStream(BlobIOSystem *creator, const std::string &file, size_t initial = 4096) :
buffer(), buffer(),
cur_size(), cur_size(),
@ -74,7 +77,8 @@ public:
// empty // empty
} }
virtual ~BlobIOStream(); /// @brief The class destructor.
~BlobIOStream() override;
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -89,16 +93,12 @@ public:
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t Read(void *, size_t Read(void *, size_t, size_t) override {
size_t,
size_t) {
return 0; return 0;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t Write(const void *pvBuffer, size_t Write(const void *pvBuffer, size_t pSize, size_t pCount) override {
size_t pSize,
size_t pCount) {
pSize *= pCount; pSize *= pCount;
if (cursor + pSize > cur_size) { if (cursor + pSize > cur_size) {
Grow(cursor + pSize); Grow(cursor + pSize);
@ -112,23 +112,22 @@ public:
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual aiReturn Seek(size_t pOffset, aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override {
aiOrigin pOrigin) {
switch (pOrigin) { switch (pOrigin) {
case aiOrigin_CUR: case aiOrigin_CUR:
cursor += pOffset; cursor += pOffset;
break; break;
case aiOrigin_END: case aiOrigin_END:
cursor = file_size - pOffset; cursor = file_size - pOffset;
break; break;
case aiOrigin_SET: case aiOrigin_SET:
cursor = pOffset; cursor = pOffset;
break; break;
default: default:
return AI_FAILURE; return AI_FAILURE;
} }
if (cursor > file_size) { if (cursor > file_size) {
@ -136,21 +135,22 @@ public:
} }
file_size = std::max(cursor, file_size); file_size = std::max(cursor, file_size);
return AI_SUCCESS; return AI_SUCCESS;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t Tell() const { size_t Tell() const override {
return cursor; return cursor;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t FileSize() const { size_t FileSize() const override {
return file_size; return file_size;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual void Flush() { void Flush() override {
// ignore // ignore
} }
@ -196,15 +196,19 @@ class BlobIOSystem : public IOSystem {
public: public:
/// @brief The default class constructor.
BlobIOSystem() : BlobIOSystem() :
baseName{AI_BLOBIO_MAGIC} { baseName{AI_BLOBIO_MAGIC} {
} }
/// @brief The class constructor with the base name.
/// @param baseName The base name.
BlobIOSystem(const std::string &baseName) : BlobIOSystem(const std::string &baseName) :
baseName(baseName) { baseName(baseName) {
// empty
} }
virtual ~BlobIOSystem() { ~BlobIOSystem() override {
for (BlobEntry &blobby : blobs) { for (BlobEntry &blobby : blobs) {
delete blobby.second; delete blobby.second;
} }
@ -263,18 +267,17 @@ public:
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual bool Exists(const char *pFile) const { bool Exists(const char *pFile) const override {
return created.find(std::string(pFile)) != created.end(); return created.find(std::string(pFile)) != created.end();
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual char getOsSeparator() const { char getOsSeparator() const override {
return '/'; return '/';
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual IOStream *Open(const char *pFile, IOStream *Open(const char *pFile, const char *pMode) override {
const char *pMode) {
if (pMode[0] != 'w') { if (pMode[0] != 'w') {
return nullptr; return nullptr;
} }
@ -284,7 +287,7 @@ public:
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual void Close(IOStream *pFile) { void Close(IOStream *pFile) override {
delete pFile; delete pFile;
} }
@ -294,7 +297,7 @@ private:
// we don't know in which the files are closed, so we // we don't know in which the files are closed, so we
// can't reliably say that the first must be the master // can't reliably say that the first must be the master
// file ... // file ...
blobs.push_back(BlobEntry(filename, child->GetBlob())); blobs.emplace_back(filename, child->GetBlob());
} }
private: private:
@ -304,8 +307,10 @@ private:
}; };
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
BlobIOStream ::~BlobIOStream() { BlobIOStream::~BlobIOStream() {
creator->OnDestruct(file, this); if (nullptr != creator) {
creator->OnDestruct(file, this);
}
delete[] buffer; delete[] buffer;
} }

View File

@ -52,10 +52,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/types.h> #include <assimp/types.h>
#include <stdint.h> #include <cstdint>
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
#include <stdlib.h> #include <cstdlib>
#endif #endif
namespace Assimp { namespace Assimp {

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -82,32 +81,27 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Read from stream /// Read from stream
size_t Read(void* pvBuffer, size_t Read(void* pvBuffer, size_t pSize, size_t pCount) override;
size_t pSize,
size_t pCount);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Write to stream /// Write to stream
size_t Write(const void* pvBuffer, size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) override;
size_t pSize,
size_t pCount);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Seek specific position /// Seek specific position
aiReturn Seek(size_t pOffset, aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override;
aiOrigin pOrigin);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Get current seek position /// Get current seek position
size_t Tell() const; size_t Tell() const override;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Get size of file /// Get size of file
size_t FileSize() const; size_t FileSize() const override;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Flush file contents /// Flush file contents
void Flush(); void Flush() override;
private: private:
FILE* mFile; FILE* mFile;
@ -116,22 +110,21 @@ private:
}; };
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT :
DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT mFile(nullptr),
: mFile(nullptr) mFilename(),
, mFilename() mCachedSize(SIZE_MAX) {
, mCachedSize(SIZE_MAX) {
// empty // empty
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename) :
DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename) mFile(pFile),
: mFile(pFile) mFilename(strFilename),
, mFilename(strFilename) mCachedSize(SIZE_MAX) {
, mCachedSize(SIZE_MAX) {
// empty // empty
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
} // ns assimp } // ns assimp

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -59,23 +58,23 @@ class ASSIMP_API DefaultIOSystem : public IOSystem {
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Tests for the existence of a file at the given path. */ /** Tests for the existence of a file at the given path. */
bool Exists( const char* pFile) const; bool Exists( const char* pFile) const override;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns the directory separator. */ /** Returns the directory separator. */
char getOsSeparator() const; char getOsSeparator() const override;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Open a new file with a given path. */ /** Open a new file with a given path. */
IOStream* Open( const char* pFile, const char* pMode = "rb"); IOStream* Open( const char* pFile, const char* pMode = "rb") override;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Closes the given file and releases all resources associated with it. */ /** Closes the given file and releases all resources associated with it. */
void Close( IOStream* pFile); void Close( IOStream* pFile) override;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Compare two paths */ /** Compare two paths */
bool ComparePaths (const char* one, const char* second) const; bool ComparePaths (const char* one, const char* second) const override;
/** @brief get the file name of a full filepath /** @brief get the file name of a full filepath
* example: /tmp/archive.tar.gz -> archive.tar.gz * example: /tmp/archive.tar.gz -> archive.tar.gz

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -42,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file DefaultLogger.hpp /** @file DefaultLogger.hpp
*/ */
#pragma once
#ifndef INCLUDED_AI_DEFAULTLOGGER #ifndef INCLUDED_AI_DEFAULTLOGGER
#define INCLUDED_AI_DEFAULTLOGGER #define INCLUDED_AI_DEFAULTLOGGER
#ifdef __GNUC__
#pragma GCC system_header
#endif
#include "LogStream.hpp" #include "LogStream.hpp"
#include "Logger.hpp" #include "Logger.hpp"
#include "NullLogger.hpp" #include "NullLogger.hpp"
@ -55,7 +59,7 @@ namespace Assimp {
class IOStream; class IOStream;
struct LogStreamInfo; struct LogStreamInfo;
/** default name of logfile */ /** default name of log-file */
#define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt" #define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt"
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
@ -72,7 +76,6 @@ struct LogStreamInfo;
* implementation of #Logger to #set(). * implementation of #Logger to #set().
* @note The whole logging stuff causes a small extra overhead for all imports. */ * @note The whole logging stuff causes a small extra overhead for all imports. */
class ASSIMP_API DefaultLogger : public Logger { class ASSIMP_API DefaultLogger : public Logger {
public: public:
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** @brief Creates a logging instance. /** @brief Creates a logging instance.
@ -121,13 +124,11 @@ public:
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** @copydoc Logger::attachStream */ /** @copydoc Logger::attachStream */
bool attachStream(LogStream *pStream, bool attachStream(LogStream *pStream, unsigned int severity) override;
unsigned int severity);
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** @copydoc Logger::detachStream */ /** @copydoc Logger::detachStream */
bool detachStream(LogStream *pStream, bool detachStream(LogStream *pStream, unsigned int severity) override;
unsigned int severity);
private: private:
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -137,22 +138,22 @@ private:
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** @briefDestructor */ /** @briefDestructor */
~DefaultLogger(); ~DefaultLogger() override;
/** @brief Logs debug infos, only been written when severity level DEBUG or higher is set */ /** @brief Logs debug infos, only been written when severity level DEBUG or higher is set */
void OnDebug(const char *message); void OnDebug(const char *message) override;
/** @brief Logs debug infos, only been written when severity level VERBOSE is set */ /** @brief Logs debug infos, only been written when severity level VERBOSE is set */
void OnVerboseDebug(const char *message); void OnVerboseDebug(const char *message) override;
/** @brief Logs an info message */ /** @brief Logs an info message */
void OnInfo(const char *message); void OnInfo(const char *message) override;
/** @brief Logs a warning message */ /** @brief Logs a warning message */
void OnWarn(const char *message); void OnWarn(const char *message) override;
/** @brief Logs an error message */ /** @brief Logs an error message */
void OnError(const char *message); void OnError(const char *message) override;
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** @brief Writes a message to all streams */ /** @brief Writes a message to all streams */
@ -167,9 +168,9 @@ private:
private: private:
// Aliases for stream container // Aliases for stream container
typedef std::vector<LogStreamInfo *> StreamArray; using StreamArray = std::vector<LogStreamInfo *>;
typedef std::vector<LogStreamInfo *>::iterator StreamIt; using StreamIt = std::vector<LogStreamInfo *>::iterator;
typedef std::vector<LogStreamInfo *>::const_iterator ConstStreamIt; using ConstStreamIt = std::vector<LogStreamInfo *>::const_iterator;
//! only logging instance //! only logging instance
static Logger *m_pLogger; static Logger *m_pLogger;
@ -182,6 +183,7 @@ private:
char lastMsg[MAX_LOG_MESSAGE_LENGTH * 2]; char lastMsg[MAX_LOG_MESSAGE_LENGTH * 2];
size_t lastLen; size_t lastLen;
}; };
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
} // Namespace Assimp } // Namespace Assimp

View File

@ -56,10 +56,22 @@ using std::runtime_error;
#pragma warning(disable : 4275) #pragma warning(disable : 4275)
#endif #endif
// ---------------------------------------------------------------------------
/**
* The base-class for all other exceptions
*/
class ASSIMP_API DeadlyErrorBase : public runtime_error { class ASSIMP_API DeadlyErrorBase : public runtime_error {
protected: protected:
/// @brief The class constructor with the formatter.
/// @param f The formatter.
DeadlyErrorBase(Assimp::Formatter::format f); DeadlyErrorBase(Assimp::Formatter::format f);
/// @brief The class constructor with the parameter ellipse.
/// @tparam ...T The type for the ellipse
/// @tparam U The other type
/// @param f The formatter
/// @param u One parameter
/// @param ...args The rest
template<typename... T, typename U> template<typename... T, typename U>
DeadlyErrorBase(Assimp::Formatter::format f, U&& u, T&&... args) : DeadlyErrorBase(Assimp::Formatter::format f, U&& u, T&&... args) :
DeadlyErrorBase(std::move(f << std::forward<U>(u)), std::forward<T>(args)...) {} DeadlyErrorBase(std::move(f << std::forward<U>(u)), std::forward<T>(args)...) {}
@ -71,19 +83,31 @@ protected:
* nullptr instead of a valid aiScene then. */ * nullptr instead of a valid aiScene then. */
class ASSIMP_API DeadlyImportError : public DeadlyErrorBase { class ASSIMP_API DeadlyImportError : public DeadlyErrorBase {
public: public:
/// @brief The class constructor with the message.
/// @param message The message
DeadlyImportError(const char *message) : DeadlyImportError(const char *message) :
DeadlyErrorBase(Assimp::Formatter::format(), std::forward<const char*>(message)) {} DeadlyErrorBase(Assimp::Formatter::format(), std::forward<const char*>(message)) {
// empty
}
/** Constructor with arguments */ /// @brief The class constructor with the parameter ellipse.
/// @tparam ...T The type for the ellipse
/// @param ...args The args
template<typename... T> template<typename... T>
explicit DeadlyImportError(T&&... args) : explicit DeadlyImportError(T&&... args) :
DeadlyErrorBase(Assimp::Formatter::format(), std::forward<T>(args)...) {} DeadlyErrorBase(Assimp::Formatter::format(), std::forward<T>(args)...) {
// empty
}
#if defined(_MSC_VER) && defined(__clang__) #if defined(_MSC_VER) && defined(__clang__)
DeadlyImportError(DeadlyImportError& other) = delete; DeadlyImportError(DeadlyImportError& other) = delete;
#endif #endif
}; };
// ---------------------------------------------------------------------------
/** FOR EXPORTER PLUGINS ONLY: Simple exception class to be thrown if an
* unrecoverable error occurs while exporting. Exporting APIs return
* nullptr instead of a valid aiScene then. */
class ASSIMP_API DeadlyExportError : public DeadlyErrorBase { class ASSIMP_API DeadlyExportError : public DeadlyErrorBase {
public: public:
/** Constructor with arguments */ /** Constructor with arguments */

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -63,8 +61,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef _WIN32 #ifdef _WIN32
# include <direct.h> # include <direct.h>
# include <stdlib.h> # include <cstdlib>
# include <stdio.h> # include <cstdio>
#else #else
# include <sys/stat.h> # include <sys/stat.h>
# include <sys/types.h> # include <sys/types.h>
@ -75,7 +73,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
class IOStream; class IOStream;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief CPP-API: Interface to the file system. /** @brief CPP-API: Interface to the file system.
@ -226,22 +224,26 @@ public:
*/ */
virtual bool ChangeDirectory( const std::string &path ); virtual bool ChangeDirectory( const std::string &path );
virtual bool DeleteFile( const std::string &file ); // -------------------------------------------------------------------
/**
* @brief Will delete the given file.
* @param file [in] The filename
* @return true, if the file wase deleted, false if not.
*/
virtual bool DeleteFile(const std::string &file);
private: private:
std::vector<std::string> m_pathStack; std::vector<std::string> m_pathStack;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE IOSystem::IOSystem() AI_NO_EXCEPT :
IOSystem::IOSystem() AI_NO_EXCEPT m_pathStack() {
: m_pathStack() {
// empty // empty
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE IOSystem::~IOSystem() {
IOSystem::~IOSystem() {
// empty // empty
} }
@ -252,8 +254,7 @@ IOSystem::~IOSystem() {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE IOStream* IOSystem::Open(const std::string& pFile, const std::string& pMode) {
IOStream* IOSystem::Open(const std::string& pFile, const std::string& pMode) {
// NOTE: // NOTE:
// For compatibility, interface was changed to const char* to // For compatibility, interface was changed to const char* to
// avoid crashes between binary incompatible STL versions // avoid crashes between binary incompatible STL versions
@ -261,8 +262,7 @@ IOStream* IOSystem::Open(const std::string& pFile, const std::string& pMode) {
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE bool IOSystem::Exists( const std::string& pFile) const {
bool IOSystem::Exists( const std::string& pFile) const {
// NOTE: // NOTE:
// For compatibility, interface was changed to const char* to // For compatibility, interface was changed to const char* to
// avoid crashes between binary incompatible STL versions // avoid crashes between binary incompatible STL versions
@ -270,8 +270,7 @@ bool IOSystem::Exists( const std::string& pFile) const {
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE bool IOSystem::ComparePaths(const std::string& one, const std::string& second) const {
bool IOSystem::ComparePaths (const std::string& one, const std::string& second) const {
// NOTE: // NOTE:
// For compatibility, interface was changed to const char* to // For compatibility, interface was changed to const char* to
// avoid crashes between binary incompatible STL versions // avoid crashes between binary incompatible STL versions
@ -279,8 +278,7 @@ bool IOSystem::ComparePaths (const std::string& one, const std::string& second)
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE bool IOSystem::PushDirectory( const std::string &path ) {
bool IOSystem::PushDirectory( const std::string &path ) {
if ( path.empty() ) { if ( path.empty() ) {
return false; return false;
} }
@ -291,8 +289,7 @@ bool IOSystem::PushDirectory( const std::string &path ) {
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE const std::string &IOSystem::CurrentDirectory() const {
const std::string &IOSystem::CurrentDirectory() const {
if ( m_pathStack.empty() ) { if ( m_pathStack.empty() ) {
static const std::string Dummy; static const std::string Dummy;
return Dummy; return Dummy;
@ -301,14 +298,12 @@ const std::string &IOSystem::CurrentDirectory() const {
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE size_t IOSystem::StackSize() const {
size_t IOSystem::StackSize() const {
return m_pathStack.size(); return m_pathStack.size();
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE bool IOSystem::PopDirectory() {
bool IOSystem::PopDirectory() {
if ( m_pathStack.empty() ) { if ( m_pathStack.empty() ) {
return false; return false;
} }
@ -319,8 +314,7 @@ bool IOSystem::PopDirectory() {
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE bool IOSystem::CreateDirectory( const std::string &path ) {
bool IOSystem::CreateDirectory( const std::string &path ) {
if ( path.empty() ) { if ( path.empty() ) {
return false; return false;
} }
@ -333,8 +327,7 @@ bool IOSystem::CreateDirectory( const std::string &path ) {
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE bool IOSystem::ChangeDirectory( const std::string &path ) {
bool IOSystem::ChangeDirectory( const std::string &path ) {
if ( path.empty() ) { if ( path.empty() ) {
return false; return false;
} }
@ -348,8 +341,7 @@ bool IOSystem::ChangeDirectory( const std::string &path ) {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE bool IOSystem::DeleteFile( const std::string &file ) {
bool IOSystem::DeleteFile( const std::string &file ) {
if ( file.empty() ) { if ( file.empty() ) {
return false; return false;
} }

View File

@ -59,7 +59,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Public ASSIMP data structures // Public ASSIMP data structures
#include <assimp/types.h> #include <assimp/types.h>
#include <exception> //#include <exception>
namespace Assimp { namespace Assimp {
// ======================================================================= // =======================================================================

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -144,26 +143,23 @@ private:
bool mSwallow, mSkip_empty_lines, mTrim; bool mSwallow, mSkip_empty_lines, mTrim;
}; };
AI_FORCE_INLINE AI_FORCE_INLINE LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim ) :
LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim ) mIdx(0),
: mIdx(0) mCur(),
, mCur() mStream(stream),
, mStream(stream) mSwallow(),
, mSwallow() mSkip_empty_lines(skip_empty_lines),
, mSkip_empty_lines(skip_empty_lines) mTrim(trim) {
, mTrim(trim) {
mCur.reserve(1024); mCur.reserve(1024);
operator++(); operator++();
mIdx = 0; mIdx = 0;
} }
AI_FORCE_INLINE AI_FORCE_INLINE LineSplitter::~LineSplitter() {
LineSplitter::~LineSplitter() {
// empty // empty
} }
AI_FORCE_INLINE AI_FORCE_INLINE LineSplitter& LineSplitter::operator++() {
LineSplitter& LineSplitter::operator++() {
if (mSwallow) { if (mSwallow) {
mSwallow = false; mSwallow = false;
return *this; return *this;
@ -203,18 +199,15 @@ LineSplitter& LineSplitter::operator++() {
return *this; return *this;
} }
AI_FORCE_INLINE AI_FORCE_INLINE LineSplitter &LineSplitter::operator++(int) {
LineSplitter &LineSplitter::operator++(int) {
return ++(*this); return ++(*this);
} }
AI_FORCE_INLINE AI_FORCE_INLINE const char *LineSplitter::operator[] (size_t idx) const {
const char *LineSplitter::operator[] (size_t idx) const {
const char* s = operator->()->c_str(); const char* s = operator->()->c_str();
SkipSpaces(&s); SkipSpaces(&s);
for (size_t i = 0; i < idx; ++i) { for (size_t i = 0; i < idx; ++i) {
for (; !IsSpace(*s); ++s) { for (; !IsSpace(*s); ++s) {
if (IsLineEnd(*s)) { if (IsLineEnd(*s)) {
throw std::range_error("Token index out of range, EOL reached"); throw std::range_error("Token index out of range, EOL reached");
@ -226,8 +219,7 @@ const char *LineSplitter::operator[] (size_t idx) const {
} }
template <size_t N> template <size_t N>
AI_FORCE_INLINE AI_FORCE_INLINE void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
const char* s = operator->()->c_str(); const char* s = operator->()->c_str();
SkipSpaces(&s); SkipSpaces(&s);
@ -242,45 +234,37 @@ void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
} }
} }
AI_FORCE_INLINE AI_FORCE_INLINE const std::string* LineSplitter::operator -> () const {
const std::string* LineSplitter::operator -> () const {
return &mCur; return &mCur;
} }
AI_FORCE_INLINE AI_FORCE_INLINE std::string LineSplitter::operator* () const {
std::string LineSplitter::operator* () const {
return mCur; return mCur;
} }
AI_FORCE_INLINE AI_FORCE_INLINE LineSplitter::operator bool() const {
LineSplitter::operator bool() const {
return mStream.GetRemainingSize() > 0; return mStream.GetRemainingSize() > 0;
} }
AI_FORCE_INLINE AI_FORCE_INLINE LineSplitter::operator line_idx() const {
LineSplitter::operator line_idx() const {
return mIdx; return mIdx;
} }
AI_FORCE_INLINE AI_FORCE_INLINE LineSplitter::line_idx LineSplitter::get_index() const {
LineSplitter::line_idx LineSplitter::get_index() const {
return mIdx; return mIdx;
} }
AI_FORCE_INLINE AI_FORCE_INLINE StreamReaderLE &LineSplitter::get_stream() {
StreamReaderLE &LineSplitter::get_stream() {
return mStream; return mStream;
} }
AI_FORCE_INLINE AI_FORCE_INLINE bool LineSplitter::match_start(const char* check) {
bool LineSplitter::match_start(const char* check) {
const size_t len = ::strlen(check); const size_t len = ::strlen(check);
return len <= mCur.length() && std::equal(check, check + len, mCur.begin()); return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
} }
AI_FORCE_INLINE AI_FORCE_INLINE void LineSplitter::swallow_next_increment() {
void LineSplitter::swallow_next_increment() {
mSwallow = true; mSwallow = true;
} }

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -43,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file LogStream.hpp /** @file LogStream.hpp
* @brief Abstract base class 'LogStream', representing an output log stream. * @brief Abstract base class 'LogStream', representing an output log stream.
*/ */
#pragma once
#ifndef INCLUDED_AI_LOGSTREAM_H #ifndef INCLUDED_AI_LOGSTREAM_H
#define INCLUDED_AI_LOGSTREAM_H #define INCLUDED_AI_LOGSTREAM_H
#ifdef __GNUC__
#pragma GCC system_header
#endif
#include "types.h" #include "types.h"
namespace Assimp { namespace Assimp {
@ -103,7 +107,6 @@ inline LogStream::~LogStream() {
// empty // empty
} }
// ------------------------------------------------------------------------------------
} // Namespace Assimp } // Namespace Assimp
#endif #endif // INCLUDED_AI_LOGSTREAM_H

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -43,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Logger.hpp /** @file Logger.hpp
* @brief Abstract base class 'Logger', base of the logging system. * @brief Abstract base class 'Logger', base of the logging system.
*/ */
#pragma once
#ifndef INCLUDED_AI_LOGGER_H #ifndef INCLUDED_AI_LOGGER_H
#define INCLUDED_AI_LOGGER_H #define INCLUDED_AI_LOGGER_H
@ -93,8 +93,6 @@ public:
Err = 8 //!< Error log message Err = 8 //!< Error log message
}; };
public:
/** @brief Virtual destructor */ /** @brief Virtual destructor */
virtual ~Logger(); virtual ~Logger();
@ -259,39 +257,30 @@ protected:
}; };
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Default constructor inline Logger::Logger() AI_NO_EXCEPT :
inline m_Severity(NORMAL) {
Logger::Logger() AI_NO_EXCEPT
: m_Severity(NORMAL) {
// empty // empty
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Virtual destructor inline Logger::~Logger() {
inline
Logger::~Logger() {
// empty // empty
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Construction with given logging severity inline Logger::Logger(LogSeverity severity) :
inline m_Severity(severity) {
Logger::Logger(LogSeverity severity)
: m_Severity(severity) {
// empty // empty
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Log severity setter inline void Logger::setLogSeverity(LogSeverity log_severity){
inline
void Logger::setLogSeverity(LogSeverity log_severity){
m_Severity = log_severity; m_Severity = log_severity;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Log severity getter // Log severity getter
inline inline Logger::LogSeverity Logger::getLogSeverity() const {
Logger::LogSeverity Logger::getLogSeverity() const {
return m_Severity; return m_Severity;
} }

View File

@ -44,9 +44,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Dummy logger * @brief Dummy logger
*/ */
#pragma once
#ifndef INCLUDED_AI_NULLLOGGER_H #ifndef INCLUDED_AI_NULLLOGGER_H
#define INCLUDED_AI_NULLLOGGER_H #define INCLUDED_AI_NULLLOGGER_H
#ifdef __GNUC__
#pragma GCC system_header
#endif
#include "Logger.hpp" #include "Logger.hpp"
namespace Assimp { namespace Assimp {

View File

@ -44,36 +44,40 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_AABB_H_INC #define AI_AABB_H_INC
#ifdef __GNUC__ #ifdef __GNUC__
# pragma GCC system_header #pragma GCC system_header
#endif #endif
#include <assimp/vector3.h> #include <assimp/vector3.h>
// ---------------------------------------------------------------------------
/**
* An axis-aligned bounding box.
*/
struct aiAABB { struct aiAABB {
C_STRUCT aiVector3D mMin; C_STRUCT aiVector3D mMin;
C_STRUCT aiVector3D mMax; C_STRUCT aiVector3D mMax;
#ifdef __cplusplus #ifdef __cplusplus
/// @brief The default class constructor.
aiAABB() aiAABB() :
: mMin() mMin(), mMax() {
, mMax() {
// empty // empty
} }
aiAABB(const aiVector3D &min, const aiVector3D &max ) /// @brief The class constructor with the minimum and maximum.
: mMin(min) /// @param min The minimum dimension.
, mMax(max) { /// @param max The maximum dimension.
aiAABB(const aiVector3D &min, const aiVector3D &max) :
mMin(min), mMax(max) {
// empty // empty
} }
/// @brief The class destructor.
~aiAABB() { ~aiAABB() {
// empty // empty
} }
#endif // __cplusplus #endif // __cplusplus
}; };
#endif // AI_AABB_H_INC #endif // AI_AABB_H_INC

View File

@ -38,6 +38,11 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file ai_assert.h
* @brief Declares the assimp-specific assertion handler.
*/
#pragma once #pragma once
#ifndef AI_ASSERT_H_INC #ifndef AI_ASSERT_H_INC
#define AI_ASSERT_H_INC #define AI_ASSERT_H_INC
@ -46,19 +51,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if defined(ASSIMP_BUILD_DEBUG) #if defined(ASSIMP_BUILD_DEBUG)
namespace Assimp namespace Assimp {
{
// Assert violation behavior can be customized: see AssertHandler.h. /// @brief Assert violation behavior can be customized: see AssertHandler.h.
ASSIMP_API void aiAssertViolation(const char* failedExpression, const char* file, int line); /// @param failedExpression The expression to validate.
/// @param file The file location
/// @param line The line number
ASSIMP_API void aiAssertViolation(const char* failedExpression, const char* file, int line);
} }
#endif
# define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0)) // Define assertion resolinig
# define ai_assert_entry() ai_assert(false) #if defined(ASSIMP_BUILD_DEBUG)
# define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
# define ai_assert_entry() ai_assert(false)
#else #else
# define ai_assert(expression) # define ai_assert(expression)
# define ai_assert_entry() # define ai_assert_entry()
#endif // ASSIMP_BUILD_DEBUG #endif // ASSIMP_BUILD_DEBUG
#endif // AI_ASSERT_H_INC #endif // AI_ASSERT_H_INC

View File

@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CAMERA_H_INC #define AI_CAMERA_H_INC
#ifdef __GNUC__ #ifdef __GNUC__
# pragma GCC system_header #pragma GCC system_header
#endif #endif
#include "types.h" #include "types.h"
@ -100,8 +100,7 @@ extern "C" {
* camera already look in the right direction. * camera already look in the right direction.
* *
*/ */
struct aiCamera struct aiCamera {
{
/** The name of the camera. /** The name of the camera.
* *
* There must be a node in the scenegraph with the same name. * There must be a node in the scenegraph with the same name.
@ -127,7 +126,6 @@ struct aiCamera
*/ */
C_STRUCT aiVector3D mUp; C_STRUCT aiVector3D mUp;
/** 'LookAt' - vector of the camera coordinate system relative to /** 'LookAt' - vector of the camera coordinate system relative to
* the coordinate space defined by the corresponding node. * the coordinate space defined by the corresponding node.
* *
@ -184,26 +182,27 @@ struct aiCamera
#ifdef __cplusplus #ifdef __cplusplus
aiCamera() AI_NO_EXCEPT aiCamera() AI_NO_EXCEPT
: mUp (0.f,1.f,0.f) : mUp(0.f, 1.f, 0.f),
, mLookAt (0.f,0.f,1.f) mLookAt(0.f, 0.f, 1.f),
, mHorizontalFOV (0.25f * (float)AI_MATH_PI) mHorizontalFOV(0.25f * (float)AI_MATH_PI),
, mClipPlaneNear (0.1f) mClipPlaneNear(0.1f),
, mClipPlaneFar (1000.f) mClipPlaneFar(1000.f),
, mAspect (0.f) mAspect(0.f),
, mOrthographicWidth (0.f) mOrthographicWidth(0.f) {}
{}
/** @brief Get a *right-handed* camera matrix from me /** @brief Get a *right-handed* camera matrix from me
* @param out Camera matrix to be filled * @param out Camera matrix to be filled
*/ */
void GetCameraMatrix (aiMatrix4x4& out) const void GetCameraMatrix(aiMatrix4x4 &out) const {
{
/** todo: test ... should work, but i'm not absolutely sure */ /** todo: test ... should work, but i'm not absolutely sure */
/** We don't know whether these vectors are already normalized ...*/ /** We don't know whether these vectors are already normalized ...*/
aiVector3D zaxis = mLookAt; zaxis.Normalize(); aiVector3D zaxis = mLookAt;
aiVector3D yaxis = mUp; yaxis.Normalize(); zaxis.Normalize();
aiVector3D xaxis = mUp^mLookAt; xaxis.Normalize(); aiVector3D yaxis = mUp;
yaxis.Normalize();
aiVector3D xaxis = mUp ^ mLookAt;
xaxis.Normalize();
out.a4 = -(xaxis * mPosition); out.a4 = -(xaxis * mPosition);
out.b4 = -(yaxis * mPosition); out.b4 = -(yaxis * mPosition);
@ -228,7 +227,6 @@ struct aiCamera
#endif #endif
}; };
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,
@ -106,8 +104,7 @@ struct aiFileIO
* the CRT. However, you can supply a custom implementation to Assimp by * the CRT. However, you can supply a custom implementation to Assimp by
* delivering a custom aiFileIO. Use this to enable reading from other sources, * delivering a custom aiFileIO. Use this to enable reading from other sources,
* such as ZIP archives or memory locations. */ * such as ZIP archives or memory locations. */
struct aiFile struct aiFile {
{
/** Callback to read from a file */ /** Callback to read from a file */
aiFileReadProc ReadProc; aiFileReadProc ReadProc;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, 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,