Results 1 to 1 of 1

Thread: animated gif support

  1. #1

    Lightbulb animated gif support

    Today I have been written a wrapper on giflib for loading gif-animated files
    I think it looks more buty for resources.xml

    <sprite name="Planet0001">
    <image file="Planet0001.gif"/>
    </sprite>

    You must download giflib library and link it to your project
    http://gnuwin32.sourceforge.net/packages/giflib.htm

    The code only loading gif animated image and not do anything more for support resource format
    It can be contain errors

    PS to clanlib: it will be very nice, if your add animated formats support (gif, apng, or something also)
    PSS I did not found support of any animated format

    PSSS Sorry for my poor English

    Code:
    #include <gif_lib.h>
    
    class GifLoader
    {
    	GifFileType* mGifFile;
    
    	struct color
    	{
    		unsigned char b;
    		unsigned char g;
    		unsigned char r;
    	};
    
    
    	void loadExtensions()
    	{
    		int ext_code = APPLICATION_EXT_FUNC_CODE;
    		GifByteType* ext_buffer;
    
    		if (DGifGetExtension(mGifFile, &ext_code, &ext_buffer) == GIF_ERROR)
    			return;
    		while (DGifGetExtensionNext(mGifFile, &ext_buffer)  == GIF_OK)
    		{
    		}
    	}
    	void loadScreenDesc()
    	{
    		if (DGifGetScreenDesc(mGifFile) == GIF_ERROR)
    			return;
    	}
    	static void setColor(GifColorType& Color, unsigned char r, unsigned char g, unsigned char b)
    	{
    		Color.Red = r;
    		Color.Green = g;
    		Color.Blue = b;
    	}
    	static ColorMapObject* getGlobalColorMap()
    	{
    		static ColorMapObject* global = nullptr;
    		if (global != nullptr)
    			return global;
    		global = new ColorMapObject;
    		global->ColorCount = 256;
    		global->BitsPerPixel = 8;
    		global->Colors = new GifColorType[global->ColorCount];
    
    		setColor(global->Colors[0], 0x00, 0x00, 0x00);
    		setColor(global->Colors[1], 0xff, 0xff, 0xff);
    		setColor(global->Colors[2], 0x00, 0xff, 0xff);
    		setColor(global->Colors[3], 0xff, 0x00, 0xff);
    		setColor(global->Colors[4], 0xff, 0xff, 0x00);
    		setColor(global->Colors[5], 0x00, 0x00, 0xff);
    		setColor(global->Colors[6], 0x00, 0xff, 0x00);
    		setColor(global->Colors[7], 0xff, 0x00, 0x00);
    		setColor(global->Colors[8], 0x80, 0x80, 0x80);
    		setColor(global->Colors[9], 0xc0, 0xc0, 0xc0);
    		setColor(global->Colors[10], 0x80, 0x00, 0x00);
    		setColor(global->Colors[11], 0x00, 0x80, 0x00);
    		setColor(global->Colors[12], 0x00, 0x00, 0x80);
    		setColor(global->Colors[13], 0x80, 0x80, 0x00);
    		setColor(global->Colors[14], 0x80, 0x00, 0x80);
    		setColor(global->Colors[15], 0x00, 0x80, 0x80);
    
    		unsigned char safecolor[] = {0x00, 0x33, 0x66, 0x99, 0xcc, 0xff};
    		for (size_t index = 0; index < 6; ++index)
    			for (size_t jindex = 0; jindex < 6; ++jindex)
    				for (size_t kindex = 0; kindex < 6; ++kindex)
    					setColor(global->Colors[16 + index * 36 + jindex * 6 + kindex], safecolor[index], safecolor[jindex], safecolor[kindex]);
    	}
    public:
    
    	GifLoader():
    	mGifFile(nullptr)
    	{
    	}
    	GifLoader(CL_String& Path):
    	mGifFile(nullptr)
    	{
    		Open(Path);
    	}
    	~GifLoader()
    	{
    		if (IsOpened())
    			DGifCloseFile(mGifFile);
    	}
    
    	bool Open(CL_String& Path)
    	{
    		mGifFile = DGifOpenFileName(Path.c_str());
    		if (IsOpened() == false)
    			return false;
    		DGifSlurp(mGifFile);
    		return true;
    	}
    
    	bool IsOpened()
    	{
    		return mGifFile != nullptr;
    	}
    
    	size_t GetBpp()
    	{
    		if (IsOpened() == false)
    			return 0;
    		return 0;
    	}
    
    	size_t GetHeight()
    	{
    		if (IsOpened() == false)
    			return 0;
    		return (size_t)mGifFile->SHeight;
    	}
    
    	size_t GetWidth()
    	{
    		if (IsOpened() == false)
    			return 0;
    		return (size_t)mGifFile->SWidth;
    	}
    
    	size_t GetFrameCount()
    	{
    		if (IsOpened() == false)
    			return 0;
    		return mGifFile->ImageCount;
    	}
    
    	bool GetFrame(size_t Index, void* buffer)
    	{
    		if (IsOpened() == false)
    			return false;
    		if (Index >= (size_t)mGifFile->ImageCount)
    			return false;
    
    		SavedImage& image = mGifFile->SavedImages[Index];
    		
    		ColorMapObject* color_map = mGifFile->SColorMap;
    		if (image.ImageDesc.ColorMap != nullptr)
    			color_map = image.ImageDesc.ColorMap;
    		if (color_map == nullptr)
    			color_map = getGlobalColorMap();
    		
    		if (color_map->BitsPerPixel != 8)
    			throw CL_Exception(cl_format("Format is not supported"));
    
    		bool IsInterlace = (image.ImageDesc.Interlace & 0x40) == 0x40;
    
    		if (IsInterlace)
    		{
    			size_t width = GetWidth();
    			size_t height = GetHeight();
    			unsigned char* raster = image.RasterBits;
    
    			auto interlace = [&](size_t start, size_t delta)
    			{
    				color* current = nullptr;
    				for (size_t jindex = start; jindex < height; jindex += delta)
    				{
    					current = (color*)buffer + jindex * width;
    					for (size_t kindex = 0; kindex < width; ++kindex, ++current, ++raster)
    					{
    						unsigned char clr_index = *raster;
    						clr_index = clr_index % color_map->ColorCount;
    
    						GifColorType& clr = color_map->Colors[clr_index];
    						current->r = clr.Red;
    						current->g = clr.Green;
    						current->b = clr.Blue;
    					}
    				}
    			};
    
    			interlace(0, 8);
    			interlace(4, 8);
    			interlace(2, 4);
    			interlace(1, 2);
    			
    		}
    		else
    		{
    			size_t pixels_count = GetHeight() * GetWidth();
    			color* current = (color*)buffer;
    			unsigned char* raster = mGifFile->SavedImages[Index].RasterBits;
    			for (size_t jindex = 0; jindex < pixels_count; ++jindex, ++current, ++raster)
    			{
    				unsigned char clr_index = *raster;
    				clr_index = clr_index % color_map->ColorCount;
    				GifColorType& clr = color_map->Colors[clr_index];
    				current->r = clr.Red;
    				current->g = clr.Green;
    				current->b = clr.Blue;
    			}
    		}
    
    		return true;
    	}
    
    	size_t GetFrameShowTime()
    	{
    		if (IsOpened() == false)
    			return 0;
    		return 0;
    	}
    
    	size_t GetLoopCount()
    	{
    		if (IsOpened() == false)
    			return 0;
    		return 0;
    	}
    };
    
    CL_Sprite LoadSprite(CL_GraphicContext& gc, const CL_String& resource_id, CL_ResourceManager* resources, const CL_ImageImportDescription& import_desc)
    {
    	CL_Resource resource = resources->get_resource(resource_id);
    	if (resource.get_type() != "sprite")
    		throw CL_Exception(cl_format("Resource '%1' is not of type 'sprite' or 'sprite_description' or 'image'", resource_id));
    
    	CL_DomNode cur_node = resource.get_element().get_first_child();
    
    	CL_String image_name = cur_node.get_attributes().get_named_item("file").get_node_value();
    
    	CL_VirtualDirectory virtual_directory = resources->get_directory(resource);
    	CL_String filepath = virtual_directory.make_path_absolute(image_name);
    
    	GifLoader gif(filepath);
    	if (gif.IsOpened() == false)
    		throw CL_Exception(cl_format("Resource '%1' cannot be loaded", resource_id));
    	CL_SpriteDescription sprite_desc;
    
    	void* frame_data = ::malloc(gif.GetWidth() * gif.GetHeight() * 3);
    
    	size_t count = gif.GetFrameCount();
    	for (size_t Index = 0; Index < count; ++Index)
    	{
    		if (gif.GetFrame(Index, frame_data) == false)
    			continue;
    
    		CL_PixelBuffer buffer(gif.GetWidth(), gif.GetHeight(), CL_TextureFormat::cl_rgb8ui, frame_data, true);
    		sprite_desc.add_frame(buffer.copy());
    		sprite_desc.set_frame_delay(Index, ((double)gif.GetFrameShowTime()) / 100);
    	}
    
    	::free(frame_data);
    
    	return CL_Sprite(gc, sprite_desc);
    }
    Last edited by _diman; 11-03-2012 at 07:26 PM. Reason: Add support interlance storing rows

Similar Threads

  1. FBO support
    By AxeD in forum Proton SDK
    Replies: 2
    Last Post: 03-14-2012, 08:26 PM
  2. [PATCH] Win32 animated cursor
    By huntercool in forum Official ClanLib SDK Forums
    Replies: 2
    Last Post: 06-18-2010, 10:53 AM
  3. Animated gif causes crash.
    By jara in forum Novashell Game Creation System
    Replies: 1
    Last Post: 01-02-2010, 02:53 PM
  4. Animated Windows and Dialogs
    By AllenJB in forum Official ClanLib SDK Forums
    Replies: 1
    Last Post: 09-20-2006, 04:28 PM
  5. Support
    By in forum Dink Smallwood HD
    Replies: 0
    Last Post: 07-08-2004, 05:37 AM

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •