aboutsummaryrefslogtreecommitdiff
path: root/src/Gif.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Gif.cpp')
-rw-r--r--src/Gif.cpp219
1 files changed, 16 insertions, 203 deletions
diff --git a/src/Gif.cpp b/src/Gif.cpp
index 6c18851..0015f50 100644
--- a/src/Gif.cpp
+++ b/src/Gif.cpp
@@ -1,216 +1,29 @@
#include "../include/Gif.hpp"
-#include "../include/FileUtil.hpp"
-
-using namespace std;
namespace dchat
{
- void* bitmapCreate(int width, int height)
- {
- return calloc(width * height, 4);
- }
-
- void bitmapDestroy(void *bitmap)
- {
- free(bitmap);
- }
-
- unsigned char* bitmapGetBuffer(void *bitmap)
- {
- return (unsigned char*)bitmap;
- }
-
- void bitmapSetOpaque(void *bitmap, bool opaque)
- {
-
- }
-
- bool bitmapTestOpaque(void *bitmap)
- {
- return false;
- }
-
- void bitmapModified(void *bitmap)
- {
-
- }
-
- const char* gifResultToString(gif_result code)
- {
- switch(code)
- {
- case GIF_INSUFFICIENT_FRAME_DATA:
- return "GIF_INSUFFICIENT_FRAME_DATA";
- case GIF_FRAME_DATA_ERROR:
- return "GIF_FRAME_DATA_ERROR";
- case GIF_INSUFFICIENT_DATA:
- return "GIF_INSUFFICIENT_DATA";
- case GIF_DATA_ERROR:
- return "GIF_DATA_ERROR";
- case GIF_INSUFFICIENT_MEMORY:
- return "GIF_INSUFFICIENT_MEMORY";
- default:
- return "Unknown gif result code";
- }
- }
-
- Gif::Gif(const boost::filesystem::path &filepath) :
- currentFrame(0),
- timeElapsedCs(0.0)
- {
- try
- {
- fileContent = getFileContent(filepath);
- }
- catch(FileException &e)
- {
- throw GifLoadException(e.what());
- }
-
- try
- {
- init();
- }
- catch(GifLoadException &e)
- {
- delete[] fileContent.data;
- throw e;
- }
- }
-
- Gif::Gif(StringView &&_fileContent) :
- fileContent(move(_fileContent)),
- currentFrame(0),
- timeElapsedCs(0.0)
+ SfmlGif::SfmlGif(StringView fileContent) : Gif(fileContent)
{
- try
- {
- init();
- }
- catch(GifLoadException &e)
- {
- delete[] fileContent.data;
- throw e;
- }
+
}
-
- void Gif::init()
+
+
+ bool SfmlGif::createTexture()
{
- gif_bitmap_callback_vt bitmapCallbacks =
- {
- bitmapCreate,
- bitmapDestroy,
- bitmapGetBuffer,
- bitmapSetOpaque,
- bitmapTestOpaque,
- bitmapModified
- };
-
- gif_create(&gif, &bitmapCallbacks);
-
- gif_result code;
- do
+ Vec2u size = getSize();
+ if(!texture.create(size.x, size.y))
{
- code = gif_initialise(&gif, fileContent.size, (unsigned char*)fileContent.data);
- if(code != GIF_OK && code != GIF_WORKING)
- {
- string errMsg = "Failed to initialize gif, reason: ";
- errMsg += gifResultToString(code);
- throw GifLoadException(errMsg);
- }
+ fprintf(stderr, "Failed to create texture for gif!\n");
+ return false;
}
- while(code != GIF_OK);
-
- if(!texture.create(gif.width, gif.height))
- throw GifLoadException("Failed to create texture for gif");
-
+
texture.setSmooth(true);
- sprite.setTexture(texture, true);
- }
-
- Gif::~Gif()
- {
- gif_finalise(&gif);
- delete[] fileContent.data;
- }
-
- sf::Vector2u Gif::getSize() const
- {
- return sprite.getTexture()->getSize();
- }
-
- void Gif::setPosition(const sf::Vector2f &position)
- {
- sprite.setPosition(position);
+ texture.generateMipmap();
+ return true;
}
-
- sf::Vector2f Gif::getPosition() const
- {
- return sprite.getPosition();
- }
-
- void Gif::setScale(const sf::Vector2f &scale)
- {
- sprite.setScale(scale);
- }
-
- void Gif::setColor(sf::Color color)
- {
- sprite.setColor(color);
- }
-
- void Gif::draw(sf::RenderTarget &target, const sf::RenderStates &renderState)
- {
- double timeElapsedMilli = (double)frameTimer.getElapsedTime().asMilliseconds();
- // If gif is not redrawn for a while, then we reset timer (gif is paused). This happens when gif is not visible and then appears visible
- // (because it's visible in window). The reason this is done is to prevent too much time between rendering gif frames, as processing a gif
- // requires to process all frames between two points in time, if elapsed frame time is too high, then we would require to process several
- // frames of gif in one application render frame.
- if(timeElapsedMilli > 1000.0)
- timeElapsedMilli = 0.0;
- double frameDeltaCs = timeElapsedMilli * 0.1; // Centisecond
- frameTimer.restart();
- timeElapsedCs += frameDeltaCs;
-
- unsigned char *image = nullptr;
- u32 startFrame = currentFrame;
- while(true)
- {
- u32 i = currentFrame % gif.frame_count;
- gif_result code = gif_decode_frame(&gif, i);
- if(code != GIF_OK)
- {
- printf("Warning: gif_decode_frame: %s\n", gifResultToString(code));
- break;
- }
-
- gif_frame &frame = gif.frames[i];
- // frame_delay is in centiseconds
- unsigned int frameDelay = frame.frame_delay;
- if(frameDelay == 0)
- frameDelay = 7;
- double fFrameDelay = (double)frameDelay;
- if(timeElapsedCs >= fFrameDelay)
- timeElapsedCs -= fFrameDelay;
- else
- break;
-
- image = (unsigned char*)gif.frame_image;
- ++currentFrame;
- }
-
- if(currentFrame != startFrame)
- {
- texture.update(image);
- // TODO: Check if this is too heavy
- texture.generateMipmap();
- sprite.setTexture(texture, true);
- }
- target.draw(sprite, renderState);
- }
-
- bool Gif::isDataGif(const StringView &data)
+
+ void SfmlGif::updateTexture(void *textureData)
{
- return data.size >= 6 && (memcmp(data.data, "GIF87a", 6) == 0 || memcmp(data.data, "GIF89a", 6) == 0);
+ texture.update((const sf::Uint8*)textureData);
}
-}
+} \ No newline at end of file