(Windows) Made GIFAnimComponent work with filenames containing Unicode characters.

This commit is contained in:
Leon Styhre 2022-03-06 12:53:20 +01:00
parent f9b2dfe037
commit cc05f778e4
2 changed files with 60 additions and 4 deletions

View file

@ -8,6 +8,10 @@
#define DEBUG_ANIMATION false #define DEBUG_ANIMATION false
#if defined(_MSC_VER) // MSVC compiler.
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "components/GIFAnimComponent.h" #include "components/GIFAnimComponent.h"
#include "Log.h" #include "Log.h"
@ -17,6 +21,7 @@
GIFAnimComponent::GIFAnimComponent() GIFAnimComponent::GIFAnimComponent()
: mFrameSize {0} : mFrameSize {0}
, mAnimFile {nullptr}
, mAnimation {nullptr} , mAnimation {nullptr}
, mFrame {nullptr} , mFrame {nullptr}
, mStartDirection {"normal"} , mStartDirection {"normal"}
@ -45,6 +50,11 @@ GIFAnimComponent::GIFAnimComponent()
mTexture->setFormat(Renderer::Texture::BGRA); mTexture->setFormat(Renderer::Texture::BGRA);
#endif #endif
mAnimIO.read_proc = readProc;
mAnimIO.write_proc = writeProc;
mAnimIO.seek_proc = seekProc;
mAnimIO.tell_proc = tellProc;
// Set component defaults. // Set component defaults.
setOrigin(0.5f, 0.5f); setOrigin(0.5f, 0.5f);
setSize(Renderer::getScreenWidth() * 0.2f, Renderer::getScreenHeight() * 0.2f); setSize(Renderer::getScreenWidth() * 0.2f, Renderer::getScreenHeight() * 0.2f);
@ -54,6 +64,14 @@ GIFAnimComponent::GIFAnimComponent()
mTexture->setLinearMagnify(false); mTexture->setLinearMagnify(false);
} }
GIFAnimComponent::~GIFAnimComponent()
{
if (mAnimFile != nullptr) {
fclose(mAnimFile);
mAnimFile = nullptr;
}
}
void GIFAnimComponent::setAnimation(const std::string& path) void GIFAnimComponent::setAnimation(const std::string& path)
{ {
if (mAnimation != nullptr) { if (mAnimation != nullptr) {
@ -106,8 +124,15 @@ void GIFAnimComponent::setAnimation(const std::string& path)
// Make sure that we can actually read this format. // Make sure that we can actually read this format.
if (FreeImage_FIFSupportsReading(fileFormat)) { if (FreeImage_FIFSupportsReading(fileFormat)) {
mAnimation =
FreeImage_OpenMultiBitmap(fileFormat, mPath.c_str(), false, true, false, GIF_PLAYBACK); #if defined(_WIN64)
mAnimFile = _wfopen(Utils::String::stringToWideString(mPath).c_str(), L"r+b");
#else
mAnimFile = fopen(mPath.c_str(), "r+b");
#endif
if (mAnimFile != nullptr)
mAnimation = FreeImage_OpenMultiBitmapFromHandle(
fileFormat, &mAnimIO, static_cast<fi_handle>(mAnimFile), GIF_PLAYBACK);
mFrame = FreeImage_LockPage(mAnimation, 0); mFrame = FreeImage_LockPage(mAnimation, 0);
FITAG* tagFrameTime {nullptr}; FITAG* tagFrameTime {nullptr};
@ -423,8 +448,8 @@ void GIFAnimComponent::render(const glm::mat4& parentTrans)
} }
if (!mHoldFrame) { if (!mHoldFrame) {
mAnimation = mAnimation = FreeImage_OpenMultiBitmapFromHandle(
FreeImage_OpenMultiBitmap(FIF_GIF, mPath.c_str(), false, true, false, GIF_PLAYBACK); FIF_GIF, &mAnimIO, static_cast<fi_handle>(mAnimFile), GIF_PLAYBACK);
mFrame = FreeImage_LockPage(mAnimation, mFrameNum); mFrame = FreeImage_LockPage(mAnimation, mFrameNum);
mPictureRGBA.clear(); mPictureRGBA.clear();

View file

@ -22,6 +22,7 @@ class GIFAnimComponent : public GuiComponent
{ {
public: public:
GIFAnimComponent(); GIFAnimComponent();
~GIFAnimComponent();
void setAnimation(const std::string& path); void setAnimation(const std::string& path);
void setKeepAspectRatio(bool value) { mKeepAspectRatio = value; } void setKeepAspectRatio(bool value) { mKeepAspectRatio = value; }
@ -40,11 +41,41 @@ public:
private: private:
void render(const glm::mat4& parentTrans) override; void render(const glm::mat4& parentTrans) override;
static inline unsigned int readProc(void* buffer,
unsigned int size,
unsigned int count,
fi_handle handle)
{
return static_cast<unsigned int>(
fread(buffer, size, count, reinterpret_cast<FILE*>(handle)));
}
static inline unsigned int writeProc(void* buffer,
unsigned int size,
unsigned int count,
fi_handle handle)
{
return static_cast<unsigned int>(
fwrite(buffer, size, count, reinterpret_cast<FILE*>(handle)));
}
static inline int seekProc(fi_handle handle, long offset, int origin)
{
return fseek(reinterpret_cast<FILE*>(handle), offset, origin);
}
static inline long int tellProc(fi_handle handle)
{
return ftell(reinterpret_cast<FILE*>(handle));
}
std::shared_ptr<TextureResource> mTexture; std::shared_ptr<TextureResource> mTexture;
std::vector<uint8_t> mPictureRGBA; std::vector<uint8_t> mPictureRGBA;
size_t mFrameSize; size_t mFrameSize;
std::chrono::time_point<std::chrono::system_clock> mAnimationStartTime; std::chrono::time_point<std::chrono::system_clock> mAnimationStartTime;
FILE* mAnimFile;
FreeImageIO mAnimIO;
FIMULTIBITMAP* mAnimation; FIMULTIBITMAP* mAnimation;
FIBITMAP* mFrame; FIBITMAP* mFrame;
std::string mPath; std::string mPath;