GifDecoder module (All OS, single frame & animated gifs)

Share your advanced PureBasic knowledge/code with the community.
kvitaliy
Enthusiast
Enthusiast
Posts: 162
Joined: Mon May 10, 2010 4:02 pm

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by kvitaliy »

Why on PureBasic there is no Gif encoder animated gifs ?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by wilbert »

kvitaliy wrote:Why on PureBasic there is no Gif encoder animated gifs ?
Netmeastro already answered this in his thread
http://www.purebasic.fr/english/viewtop ... 82#p432782
Windows (x64)
Raspberry Pi OS (Arm64)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by wilbert »

I posted v1.0.6 in the first post of this thread.
It fixes a small problem on Windows.

I also coded a fully working (animated) gif explorer.
You can select a file on the left and it shows on the right :)

Code: Select all

EnableExplicit

IncludeFile "GifDecoder.pbi"

InitSprite()

Define Event, Item, NewFile, FileName.s
Define d, t, f, frame_count, *m
Dim Frames.GifDecoder::GIF_Frame(0)

If OpenWindow(0, 0, 0, 720, 420, "[Animated] GIF explorer", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  EnableWindowDrop(0, #PB_Drop_Files, #PB_Drag_Copy)
  ExplorerListGadget(0, 10, 10, 280, 400, GetHomeDirectory())
  OpenWindowedScreen(WindowID(0), 310, 10, 400, 400)
  ClearScreen($D8D8D8)
  FlipBuffers()
  
  f = 0
  Repeat
    Event = WindowEvent()
    
    NewFile = #False
    If Event = #PB_Event_WindowDrop
      FileName = StringField(EventDropFiles(), 1, #LF$)
      SetGadgetState(0, -1)
      NewFile = #True
    ElseIf EventType() = #PB_EventType_Change
      Item = GetGadgetState(0)
      If Item >= 0
        FileName = GetGadgetText(0) + GetGadgetItemText(0, Item)
        NewFile = #True
      EndIf
    EndIf
    
    If NewFile And FileSize(FileName) > 32 And ReadFile(0, FileName)
      *m = AllocateMemory(Lof(0), #PB_Memory_NoClear)
      ReadData(0, *m, Lof(0))
      CloseFile(0)
      
      If GifDecoder::FrameCount(*m)
        
        ; remove existing sprites
        For f = 0 To ArraySize(Frames())
          If Frames(f)\image
            FreeSprite(Frames(f)\image)
          EndIf
        Next
        
        ; get new sprites
        GifDecoder::GetRenderedFrames(Frames(), *m, 0, 1)
        frame_count = ArraySize(Frames()) + 1
        If Frames(0)\width > 400 Or Frames(0)\height > 400
          For f = 0 To frame_count - 1
            With Frames(f)
              If \width > \height
                ZoomSprite(\image, 400, 400 * \height / \width)  
              Else
                ZoomSprite(\image, 400 * \width / \height, 400)  
              EndIf
            EndWith
          Next    
        EndIf
        
        ; single frame ?, display now
        If frame_count = 1
          ClearScreen($D8D8D8)
          DisplayTransparentSprite(frames(0)\image, 0, 0)
          FlipBuffers()
        Else
          f = 0 : d = 0
        EndIf
        
      EndIf
      FreeMemory(*m)
    EndIf
    
    If frame_count > 1 And ElapsedMilliseconds() - t >= d
      While frames(f)\delay = 0
        f = (f + 1) % frame_count
      Wend
      With frames(f)
        ClearScreen($D8D8D8)
        DisplayTransparentSprite(\image, 0, 0)
        FlipBuffers()
        d = \delay
        t = ElapsedMilliseconds()
      EndWith
      f = (f + 1) % frame_count
    EndIf
    
    Delay(4)
    
  Until Event = #PB_Event_CloseWindow
EndIf
Last edited by wilbert on Tue Dec 17, 2013 12:32 pm, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by Kwai chang caine »

Thanks a lot WILBERT to interesting you too, to this splendid format of picture 8)
I have testing all my pictures and all works perfectly on W7 pb 5.20 :shock:

Image

All my friends want absolutely come here, for thanks you :oops:
ImageImage
ImageImage
ImageImage
ImageImage
ImageImage
ImageImage
ImageImage
Image
Image

All works with your splendid explorer !!! :shock: :D

Thanks a lot to you MASTER WILBERT for sharing your splendid decoder

And also thanks for all the others members, TsSoft, Netmaestro, etc.. who works for try to adding a GIF decoder to PB since several years 8)

For KCC...it's christmas before christmas !!!!
ImageThe happiness is a road...
Not a destination
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by wilbert »

Kwaï chang caïne wrote:All works with your splendid explorer !!! :shock: :D
Glad to hear that :D
That was the goal (that all animated gif files would work).
Have fun with it (and with the gadget Netmaestro created) :!:
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by Kwai chang caine »

Never you believe how much i'm happy with your great presents 8)
It's a gift worthy of fairy tales christmas :shock:
It's thanks to MASTERS like you, NETMAESTRO, SPARKIE, SROD, IDLE, LUIS, GNOZAL, FLYPE, DANILO, TSSOFT, KIFFY, ZOMBIE, EINANDER, FREAK, FRED etc .......and numerous others (Excuse me by advance, for all i can quote :oops:) that i love programming ..... 8)
Perhaps someone say : "It's perhaps not a good thing !!!" :? :mrgreen:

You and NETMAESTRO I love you !!!
Image

All MASTERS MEMBERS, have the best christmas of the world !!!
ImageThe happiness is a road...
Not a destination
User avatar
J. Baker
Addict
Addict
Posts: 2178
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by J. Baker »

Very nice wilbert! And thanks for the Gif Explorer too! ;)

Image
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef

Mac: 10.13.6 / 1.4GHz Core 2 Duo / 2GB DDR3 / Nvidia 320M
PC: Win 7 / AMD 64 4000+ / 3GB DDR / Nvidia 720GT


Even the vine knows it surroundings but the man with eyes does not.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by wilbert »

I posted v1.1.0 of my decoder.
It's a bit experimental at this stage so needs some testing.
I added an Animate procedure that makes it easier to use the decoder together with an ImageGadget.

Here's an updated version of the explorer code I posted earlier to use an ImageGadget instead of a WindowedScreen

Code: Select all

EnableExplicit

IncludeFile "GifDecoder.pbi"

Define Event, Item, NewFile, FileName.s, *m

If OpenWindow(0, 0, 0, 820, 520, "[Animated] GIF explorer", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  SetWindowColor(0, $EEEEEE)
  EnableWindowDrop(0, #PB_Drop_Files, #PB_Drag_Copy)
  ExplorerListGadget(0, 10, 10, 280, 500, GetHomeDirectory())
  ImageGadget(1, 310, 10, 500, 500, 0)
  
  Repeat
    Event = WaitWindowEvent()
    
    NewFile = #False
    If Event = #PB_Event_WindowDrop
      FileName = StringField(EventDropFiles(), 1, #LF$)
      SetGadgetState(0, -1)
      NewFile = #True
    ElseIf EventType() = #PB_EventType_Change
      Item = GetGadgetState(0)
      If Item >= 0
        FileName = GetGadgetText(0) + GetGadgetItemText(0, Item)
        NewFile = #True
      EndIf
    EndIf
    
    If NewFile And FileSize(FileName) > 32 And ReadFile(0, FileName)
      *m = AllocateMemory(Lof(0), #PB_Memory_NoClear)
      ReadData(0, *m, Lof(0))
      CloseFile(0)
      GifDecoder::Animate(1, *m, #True, GetWindowColor(0), 500, 500)
    EndIf
    
   Until Event = #PB_Event_CloseWindow
EndIf
And also a small embedded gif example

Code: Select all

IncludeFile "GifDecoder.pbi"

If OpenWindow(0, 0, 0, 220, 100, "[Animated] GIF demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ImageGadget(0, 10, 10, 200, 80, 0)
  GifDecoder::Animate(0, ?icon_lol)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

DataSection
  icon_lol:
    Data.q $000F613938464947,$454545000DB3000F,$FFFF00000000EAFF,$FF00C9FF00CEFFFF,$13FDFF009DFE00B4
    Data.q $FFFFC7FFFF93FEFF,$0000000000E5FFEB,$0BFF210000000000,$455041435354454E,$0000000103302E32
    Data.q $000D00140504F921,$0F000F000000002C,$6A0949B05A040000,$06172252A5D5B89D,$130079410480822C
    Data.q $0A7254AE9C6898A0,$5C29EB729A801E31,$2543058EC9B00561,$4A69440094A63C01,$103B7681A909412D
    Data.q $F02DDB80AC00590C,$D251A66AA3020434,$780C016EE09C7885,$21002264B7633103,$2C000D00140504F9
    Data.q $0007000B00020002,$A85B2449B0130400,$61F09FE8ABCDEB38,$210044D9D90C34A2,$2C000D000A0504F9
    Data.q $0002000500070005,$8D6A394850050400,$0D000A0504F92100,$0005000700052C00,$2948300504000002
    Data.q $0A0504F921008D6A,$000700052C000D00,$5005040000020005,$04F921008D6A3948,$00052C000D001405
    Data.q $0400000200050007,$3B008D6A29483005
EndDataSection
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by Kwai chang caine »

This day i need your splendid code for using GIF 8)
But i have a little problem :|
How can i do for stoping the animation immediately
Because i try to read GIF and JPG in the same GadgetImage and when i send a JPG in the GadgetImage after i have send a GIF, the JPG appears only few seconds, and the GIF of before appears as news replacing my JPG :|

Edit:
I have found, that works, but i want to know if it's threadsafe and a good method

Code: Select all

Procedure SetImageGadgetGif(GadgetImage.l, ImageId.l, CouleurFond.l, LargeurMax.i = 1000, HauteurMax.i = 1000)
 
 Structure Animation
    Target.i  ; image gadget to target
    *GIF_Data
    ThreadID.i
    MaxWidth.i
    MaxHeight.i
    BgColor.l
    FreeData.l
    Quit.l    ; quit flag
  EndStructure
  
 Static *PtrAnimate.Animation
 
 If ImageId
  *PtrAnimate = GifDecoder::Animate(GadgetImage, ImageId, #True, CouleurFond, LargeurMax, HauteurMax)
 Else
  If *PtrAnimate And IsThread(*PtrAnimate\ThreadID)
   KillThread(*PtrAnimate\ThreadID)
  EndIf 
 EndIf 

EndProcedure
If i send a zero in my procedure SetImageGadgetGif() before sending my JPG...the thread is stopped before

Code: Select all

SetImageGadgetGif(#GadgetImage, 0, 0)
ImageThe happiness is a road...
Not a destination
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by wilbert »

I think the safest way would be setting the quit flag.

Code: Select all

*PtrAnimate\Quit = #True
If you do that it should stop.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by Kwai chang caine »

Hello WILBERT happy to talk to you :D

First ...thanks for your answer, i try it immediately 8)

Next, and just for your information, i have found two pictures not really working with your splendid library

This is the first (I love it, it's like fish in aquarium..i can watch it a long time, and for sleeping it's the top :mrgreen:)
Image
With IE all are good..but with your code the sheep win the 110 meter hurdle championship :lol:
ImageThe happiness is a road...
Not a destination
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by wilbert »

Kwai chang caine wrote:This is the first (I love it, it's like fish in aquarium..i can watch it a long time, and for sleeping it's the top :mrgreen:)
Image
With IE all are good..but with your code the sheep win the 110 meter hurdle championship :lol:
It's a bad gif. It specifies a frame delay of 1/100 sec.
Different decoders handle this in different ways. Most browsers set a minimum delay of for example 10/100 sec but in theory it's possible you want to create a gif file that runs faster.
Changing the decoder to the way most browsers work would cause problems with animated gifs that are intended to run fast so there is no perfect solution.
What I could do is add a feature to override the frame delay so you could set it manually.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by Kwai chang caine »

If you found a solution, even manually it's already better than nothing 8)
Because i don't know if my sheep can live again a long time at this speed :lol: :lol:
Image

Another thing, i have try like you say

Code: Select all

*PtrAnimate\Quit = #True
But apparently that not stop also faster the thread, because my JPG image continue to disappear :(
Never mind, with the KillThread solution, that works...and you know KCC is already so happy when that's works :shock: :wink:
Even if the processor suffer a little bit :mrgreen: :oops:
ImageThe happiness is a road...
Not a destination
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by wilbert »

Once you set the Quit flag, it can take one frame before the thread closes so you would have to use it in combination with WaitThread().
KillThread() will stop the thread but won't free the frame images. If you do it often it will result in a memory leak.
Another thing you could try (instead of WaitThread) is not only set the quit flag but also *PtrAnimate\Target = 0

I updated the module in the first post and added an extra MinDelay argument to the GifDecoder::Animate() procedure.
It allows you to set the minimum frame delay in msec. If you set it to 100 it should be easier to count your jumping sheep :wink:
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: GifDecoder module (All OS, single frame & animated gifs)

Post by Kwai chang caine »

thanks a lot WILBERT
i try soon your tips,because i'm on my phone

you are an angel
Image
ImageThe happiness is a road...
Not a destination
Post Reply