The MASM Forum

General => The Campus => Topic started by: bluedevil on May 18, 2017, 02:31:14 AM

Title: Viewing Animated GIF files
Post by: bluedevil on May 18, 2017, 02:31:14 AM
Hello people;
I have attached a project which loads an animated GIF using AniGIF library.
We should include the library
Include AniGIF.inc
IncludeLib AniGIF.lib
PUBLIC hInstance

Very important to declare hInstance as PUBLIC!!

Under Window procedure call two functions
PencereIslemi proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
invoke InitAniGIF ;Starts animation
mov eax,uMsg
.if eax==WM_INITDIALOG

              .
              .
              .
              .


.elseif eax==WM_COMMAND
              .
              .
              .
              .
.elseif eax==WM_CLOSE
              .
              .
.else
mov eax,FALSE
ret
.endif
invoke TerminateAniGIF ;HERE terminates animation
mov eax,TRUE
ret

PencereIslemi endp


Very important part :
#define logoGif 501
logoGif RCDATA    DISCARDABLE "Res/nelieltransform.gif"
  CONTROL "#501",aniLogo,"AniGIF",0x50000000,6,3,333,184,0x00000000

You have to write down "AniGIF" to Control section
And you have to define GIF as RCDATA


I want to ask is there any other options to achieve this goal without using these external -AniGIF- libraries?

@jj2007 you have included executables several times to forum. Bu you didnt share any source codes about this issue. Are you also using this libraries? If not can you share any sources with me?

Thanks for all =)

Because of the GIF file the zip file size  is ~700kb So here is a link to Github and Zippyshare
https://github.com/blue-devil/Assembly/tree/master/RadASM/Masm/Projects/GifView
http://www118.zippyshare.com/v/Nwse3uPN/file.html
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 18, 2017, 04:41:16 AM
Quote from: blue_devil on May 18, 2017, 02:31:14 AM@jj2007 you have included executables several times to forum. Bu you didnt share any source codes about this issue. Are you also using this libraries? If not can you share any sources with me?

No, I use only the built-in Windows library GdiPlus. Here is a source:

guiTimerMs=50            ; more is slower
GuiParas equ "Simple GIF viewer", w240, h200
include \masm32\MasmBasic\Res\MbGui.asm      ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)

Event Paint
  .if CL$(?)
      GuiImage CL$(), fit      ; drag an animated gif over the exe
  .else
      GuiImage 100, fit      ; or show tweetie from the resources
  .endif
GuiEnd


Full project attached, needs MasmBasic (http://masm32.com/board/index.php?topic=94.0), of course.

\masm32\MasmBasic\Res\MbGui.asm is a public part of MasmBasic; the rest is closed source, but I could give you a personal exclusive license to disassemble the closed part, if you give me a good reason :bgrin:

For example, you could insert an int 3 into line 15572 of \Masm32\MasmBasic\MasmBasic.inc ;)
Title: Re: Viewing Animated GIF files
Post by: bluedevil on May 18, 2017, 05:58:57 AM
Quote from: jj2007 on May 18, 2017, 04:41:16 AM
Quote from: blue_devil on May 18, 2017, 02:31:14 AM@jj2007 you have included executables several times to forum. Bu you didnt share any source codes about this issue. Are you also using this libraries? If not can you share any sources with me?

No, I use only the built-in Windows library GdiPlus. Here is a source:

guiTimerMs=50            ; more is slower
GuiParas equ "Simple GIF viewer", w240, h200
include \masm32\MasmBasic\Res\MbGui.asm      ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)

Event Paint
  .if CL$(?)
      GuiImage CL$(), fit      ; drag an animated gif over the exe
  .else
      GuiImage 100, fit      ; or show tweetie from the resources
  .endif
GuiEnd


Full project attached, needs MasmBasic (http://masm32.com/board/index.php?topic=94.0), of course.

\masm32\MasmBasic\Res\MbGui.asm is a public part of MasmBasic; the rest is closed source, but I could give you a personal exclusive license to disassemble the closed part, if you give me a good reason :bgrin:

For example, you could insert an int 3 into line 15572 of \Masm32\MasmBasic\MasmBasic.inc ;)

1. As a MASM32 coder i cannot understand your way of codes. In my MASM directory i have a MasmBasic directory too. But it says:
Quote; The smallprint: this library is provided "as is", and the usual disclaimers apply.
; This help file refers to MasmBasic version 4 October 2012
; -----------------------------------------------------------------------
include \masm32\MasmBasic\MasmBasic.inc   ; this line substitutes include \masm32\include\masm32rt.inc
Is this old or very old version?
2. What is .ASC file doing exactly?
3. Generally hutch-- gives more pure assembly samples. But i always open to new knowledge. But here i have 2 issues.
3.a. I want to learn assembly, all syntaxes, rules, constants and everything. And in a very low-level way
3.b. I want to use RadASM as an IDE because i am the guy translated it in Turkish so i know every part of it.
4.When i see your code above i cannot implement that inside my own code :( Because i cannot understand what GuiImage does, what CL does and what $ does after CL?
5.At the end there must be a windows API but i still couldn't get there :(
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 18, 2017, 07:22:02 AM
Quote from: blue_devil on May 18, 2017, 05:58:57 AM
1. As a MASM32 coder i cannot understand your way of codes. In my MASM directory i have a MasmBasic directory too. But it says:
Quote; The smallprint: this library is provided "as is", and the usual disclaimers apply.
; This help file refers to MasmBasic version 4 October 2012
; -----------------------------------------------------------------------
include \masm32\MasmBasic\MasmBasic.inc   ; this line substitutes include \masm32\include\masm32rt.inc
Is this old or very old version?

Almost five years old. Incredibly old. How old is your current smartphone? The current MasmBasic version is dated 12 May 2017 (http://masm32.com/board/index.php?topic=94.0). But caution, installing MasmBasic is incredibly complicated. Well, actually not that complicated, maybe installing GCC or VS Community can give you even more headaches ::)

Quote2. What is .ASC file doing exactly?

Assembler Source Code. Extract AnimatedGifViewer.asc and Tweetie.gif to any folder, then open the *.asc in \Masm32\MasmBasic\RichMasm.exe and hit the F6 key. The two files in the zip are the complete project.

Quote3. Generally hutch-- gives more pure assembly samples. But i always open to new knowledge. But here i have 2 issues.
3.a. I want to learn assembly, all syntaxes, rules, constants and everything. And in a very low-level way

Hutch is a very good at low level assembler, but he is equally good at writing macros and high-level library functions, see \masm32\help\masm32.chm

The question "is pure low level assembler better than using macros?" is very important in the early stages of learning. Later on, you will still be able to write low level assembler, but if you don't use macros, you will never go significantly beyond the hello world proggie stage. If you wonder what "significantly" means: The source of the RichMasm editor is currently close to 20,000 lines. That is a medium size program. Theoretically, one could write such a program in push push call style, have fun.

Quote3.b. I want to use RadASM as an IDE because i am the guy translated it in Turkish so i know every part of it.

It should be is possible*) to use MasmBasic from RadASM - after all, it's assembler, in the sense of: ML.exe can digest a MasmBasic source, from version 6.15 onwards. I haven't tested it, though (and I prefer HJWasm for building my stuff). Has anybody tested using MB in RadASM?

Quote4.When i see your code above i cannot implement that inside my own code :( Because i cannot understand what GuiImage does, what CL does and what $ does after CL?
5.At the end there must be a windows API but i still couldn't get there :(

There is a MasmBasic manual, and there is one for OllyDbg, too.

*) RadAsm assembles the source without problems, but convincing the IDE to add the resource and compile it is a major challenge :dazzled: In the end, I gave up with the *.rc file, instead I copied the rsrc.res from the MasmBasic folder and changed the linker's commandline by hand, adding rsrc.res. The full RadASM project is attached.
Title: Re: Viewing Animated GIF files
Post by: qWord on May 18, 2017, 11:35:28 AM
blue_devil ,

a short demonstration using Gdiplus. See msdn for deatils of the used functions. Requires foo.gif in current dir and cmd option /Zp8
include \masm32\include\masm32rt.inc
include \masm32\include\gdiplus.inc
includelib \masm32\lib\gdiplus.lib
.686

.data?
    hInstance   HINSTANCE   ?
.code

WndProc proto hWnd:HWND,uMgs:UINT,wParam:WPARAM,lParam:LPARAM

main proc
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL gsi:GdiplusStartupInput
LOCAL gtkn:PULONG

    mov gsi.GdiplusVersion,1
    mov gsi.DebugEventCallback,0
    mov gsi.SuppressBackgroundThread,0
    mov gsi.SuppressExternalCodecs,0
    invoke GdiplusStartup,ADDR gtkn,ADDR gsi,0

    mov hInstance,rv(GetModuleHandle,0)
    mov wc.hInstance,eax
    mov wc.cbSize,SIZEOF wc
    mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_SAVEBITS
    mov wc.lpfnWndProc,OFFSET WndProc
    mov wc.cbClsExtra,0
    mov wc.cbWndExtra,0
    mov wc.hIcon,rv(LoadIcon,0,IDI_APPLICATION)
    mov wc.hIconSm,eax
    mov wc.hCursor,rv(LoadCursor,0,IDC_ARROW)
    mov wc.lpszMenuName,0
    mov wc.hbrBackground,0
    mov wc.lpszClassName,chr$("Win32Wnd")
    invoke RegisterClassEx,ADDR wc
   
    mov ebx,ASM(mov edi,rv(GetSystemMetrics,SM_CXSCREEN))
    mov ecx,rv(GetSystemMetrics,SM_CYSCREEN)
    shr ebx,1
    shr eax,1
    shr edi,2
    shr ecx,2
    fnx esi = CreateWindowEx,0,wc.lpszClassName,"Foo32",WS_VISIBLE or WS_SYSMENU or WS_MAXIMIZEBOX or WS_MINIMIZEBOX or WS_SIZEBOX,edi,ecx,ebx,eax,0,0,hInstance,0
    invoke UpdateWindow,esi
   
    .while 1
        invoke GetMessage,ADDR msg,0,0,0
        .break .if !eax || eax == -1
        invoke TranslateMessage,ADDR msg
        invoke DispatchMessage,ADDR msg     
    .endw

    invoke GdiplusShutdown,gtkn
    invoke ExitProcess,msg.wParam
   
main endp

getDelayProp proc image:PVOID
LOCAL propSize:UINT
LOCAL delayProp: ptr PropertyItem

    invoke GdipGetPropertyItemSize,image, PropertyTagFrameDelay, ADDR propSize
   
    mov delayProp,alloc(propSize)

    invoke GdipGetPropertyItem,image, PropertyTagFrameDelay, propSize, delayProp

    mov eax,delayProp
    ret
   
getDelayProp endp

getFrameCount proc image:PVOID, dimGuid: ptr GUID
LOCAL dimCount:DWORD
LOCAL dimensionIDs: ptr GUID
LOCAL count:DWORD
   
    invoke GdipImageGetFrameDimensionsCount,image, ADDR dimCount
   
    .if eax || dimCount != 1
        xor eax,eax
        ret
    .endif
   
    imul edx,dimCount,SIZEOF GUID
    mov dimensionIDs,alloc(edx)
     
    invoke GdipImageGetFrameDimensionsList,image,dimensionIDs, dimCount
   
    invoke GdipImageGetFrameCount,image,dimensionIDs,ADDR count
   
    invoke RtlMoveMemory,dimGuid,dimensionIDs,SIZEOF GUID

    free dimensionIDs
   
    mov eax,count
    ret
   
getFrameCount endp


getDelayForFrame proc delayProp:ptr PropertyItem, frameNo:DWORD
   
   
    mov edx,delayProp
    assume edx: ptr PropertyItem
   
    mov ecx,[edx]._length
    .if [edx].nType == PropertyTagTypeLong ||[edx].nType == PropertyTagTypeSLONG
        shr ecx,2
    .elseif [edx].nType == PropertyTagTypeShort
        shr ecx,1
    .elseif [edx].nType != PropertyTagTypeByte
        ; error case
        int 3
    .endif
   
    .if ecx < frameNo
        ; error case
        int 3
    .endif
   
    mov ecx,[edx].value
    mov eax,frameNo
    .if [edx].nType == PropertyTagTypeLong ||[edx].nType == PropertyTagTypeSLONG
        mov eax,DWORD ptr [ecx + DWORD*eax]
    .elseif [edx].nType == PropertyTagTypeShort
        movzx eax,WORD ptr [ecx + WORD*eax]
    .else
        movzx eax,BYTE ptr [ecx + eax]
    .endif
   
    assume edx: nothing
   
    imul eax,10 ; GIF delay unit is 1/100s => mul. with 10 to get milliseconds
   
    ret
   
getDelayForFrame endp

WndProc proc uses ebx esi hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL rect:RECT
LOCAL ps:PAINTSTRUCT
LOCAL graphics:PVOID

    .data?
        gifImage PVOID ?
        delayProp  PVOID ? ; ptr PropertyItem
        frameCount SDWORD ?
        frameDimGuid GUID <>
        frameNumber SDWORD ?
    .code

    .if uMsg == WM_CLOSE
        invoke PostQuitMessage,0
    .elseif uMsg == WM_DESTROY
   
        invoke GdipDisposeImage, gifImage
       
        free delayProp
       
    .elseif uMsg == WM_CREATE
       
        fnx GdipLoadImageFromFile,L"foo.gif", ADDR gifImage
       
        fnx delayProp = getDelayProp,gifImage
               
        fnx frameCount = getFrameCount,gifImage,ADDR frameDimGuid
       
        .if frameCount > 1
           
            add frameNumber,1
           
            invoke getDelayForFrame,delayProp,frameNumber
            invoke SetTimer,hWnd,123,eax,NULL
           
        .endif
       
       
    .elseif uMsg == WM_TIMER && wParam == 123
       
        invoke KillTimer,hWnd,123
       
        invoke GdipImageSelectActiveFrame,gifImage, ADDR frameDimGuid, frameNumber

        mov eax,frameNumber
        add eax,1
        .if eax == frameCount
            xor eax,eax
        .endif
        mov frameNumber,eax
       
        invoke getDelayForFrame,delayProp,eax
        invoke SetTimer,hWnd,123,eax,NULL
       
        invoke InvalidateRect,hWnd,NULL,FALSE
       
    .elseif uMsg == WM_PAINT
   
        invoke BeginPaint,hWnd,ADDR ps
       
        invoke GetClientRect,hWnd,ADDR rect
       
        fnx ebx = CreateCompatibleDC,ps.hdc
        invoke CreateCompatibleBitmap,ps.hdc,rect.right,rect.bottom
        fnx esi = SelectObject,ebx,eax
       
        invoke GdipCreateFromHDC,ebx, ADDR graphics

        invoke GdipGraphicsClear,graphics,-1
       
        invoke GdipDrawImageI,graphics, gifImage,0,0
       
        invoke BitBlt,ps.hdc,0,0,rect.right,rect.bottom,ebx,0,0,SRCCOPY
       
        invoke DeleteObject,rv(SelectObject,ebx,esi)
        invoke DeleteDC,ebx
        invoke GdipDeleteGraphics,graphics
        invoke EndPaint,hWnd,ADDR ps
       
    .else
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .endif
   
    xor eax,eax
    ret
   
WndProc endp
end main


BTW: What has happen to this forum? "Use masmbasic" is now the accepted default answer to any upcoming question?
Title: Re: Viewing Animated GIF files
Post by: newrobert on May 18, 2017, 11:38:18 AM
i remember there was static gif lib, no ani gif lib.
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 18, 2017, 04:40:11 PM
Quote from: qWord on May 18, 2017, 11:35:28 AMBTW: What has happen to this forum? "Use masmbasic" is now the accepted default answer to any upcoming question?

OP asked explicitly how I did it. Apart from this post, I made a quick check and found out that my last 28 posts had nothing to do with MasmBasic. So your remark proves that you are German and nothing else. Btw you should try MasmBasic, much faster than C and (no) [ugly] {brackets} or se;mi;co;lons;  8)
Title: Re: Viewing Animated GIF files
Post by: fearless on May 18, 2017, 10:45:04 PM
Quote from: qWord on May 18, 2017, 11:35:28 AM
and cmd option /Zp8

Hi qWord, thanks for the example, just wondering why the /Zp8 is required? is it some alignment with data structures or for the gif file. Thanks in advance
Title: Re: Viewing Animated GIF files
Post by: HSE on May 18, 2017, 11:42:53 PM
Hi qWord!

Without /Zp I have a crash in:        mov eax,DWORD ptr [ecx + DWORD*eax]
in theory is a 4 bytes problem. And work perfect with /Zp4  :t


Title: Re: Viewing Animated GIF files
Post by: hutch-- on May 19, 2017, 12:30:09 AM
qword,

I am not sure why but after building it with the /Zp8 option and placing an animated gif in the same directory, it builds with no errors but will not run. Ends up in memory but nothing shows.
Title: Re: Viewing Animated GIF files
Post by: qWord on May 19, 2017, 12:34:39 AM
Quote from: fearless on May 18, 2017, 10:45:04 PMjust wondering why the /Zp8 is required?
It the default structure member alignment in Win32 and should be always used to avoid strange errors. For most structures it has no effect because of their layout. In the above example it is the PropertyItem structure that has a WORD-sized member breaking the alignment of the following pointer (and yes, for this structure also Zp4 works, because there are no 64 bit width members in it)

Quote from: jj2007 on May 18, 2017, 04:40:11 PM
OP asked explicitly how I did it.
He explicit ask how do it with plain WinAPI.

Quote from: jj2007 on May 18, 2017, 04:40:11 PMApart from this post, I made a quick check and found out that my last 28 posts had nothing to do with MasmBasic.
just ignoring the several thousand other post you did with more or less "advertising".

Quote from: jj2007 on May 18, 2017, 04:40:11 PMSo your remark proves that you are German and nothing else
Yes Mr. "I know the answer, but I won't give it to you"
Title: Re: Viewing Animated GIF files
Post by: qWord on May 19, 2017, 12:36:46 AM
Quote from: hutch-- on May 19, 2017, 12:30:09 AM
I am not sure why but after building it with the /Zp8 option and placing an animated gif in the same directory, it builds with no errors but will not run. Ends up in memory but nothing shows.
strange - can you upload the EXE?
Title: Re: Viewing Animated GIF files
Post by: qWord on May 19, 2017, 12:43:36 AM
Attached my build.
Title: Re: Viewing Animated GIF files
Post by: hutch-- on May 19, 2017, 01:12:37 AM
Just tried your build, will not run on my Win10 64 bit.

I have attached the source and how I built it and used your GIF file.

I could not get your window to start so I put all of your GDIP code in another window but it was looking for code that was not available. Are you using a special GDI plus include file ?
Title: Re: Viewing Animated GIF files
Post by: qWord on May 19, 2017, 01:25:15 AM
Your build works fine on win7x64

I guess there is some incompatibility in my code - would require to analyze the return values of the GDIP functions. I will try it later with a Win10 dev VM.

Quote from: hutch-- on May 19, 2017, 01:12:37 AMAre you using a special GDI plus include file ?
Actual not.
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 19, 2017, 01:48:41 AM
Quote from: hutch-- on May 19, 2017, 01:12:37 AM
Just tried your build, will not run on my Win10 64 bit.

On Win10, CreateWindowEx fails with invalid menu handle.

On Win7-64, the OS set esi initially to zero, so this succeeds:
    fnx esi = CreateWindowEx,0,wc.lpszClassName,"Foo32",WS_VISIBLE or WS_SYSMENU or WS_MAXIMIZEBOX or WS_MINIMIZEBOX or WS_SIZEBOX,edi,ecx,ebx,eax,0,esi,hInstance,0

And in any case, mov ecx,[edx].value will fail unless the linker is explicitly told to align the structure. The problem is lack of a padding word in Windows.inc (the default Masm32 strategy) for that structure.
Title: Re: Viewing Animated GIF files
Post by: qWord on May 19, 2017, 01:58:37 AM
Quote from: jj2007 on May 19, 2017, 01:48:41 AM
On Win10, CreateWindowEx fails with invalid menu handle.

On Win7-64, the OS set esi initially to zero, so this succeeds:
    fnx esi = CreateWindowEx,0,wc.lpszClassName,"Foo32",WS_VISIBLE or WS_SYSMENU or WS_MAXIMIZEBOX or WS_MINIMIZEBOX or WS_SIZEBOX,edi,ecx,ebx,eax,0,esi,hInstance,0
yes, thats it.
Title: Re: Viewing Animated GIF files
Post by: hutch-- on May 19, 2017, 02:15:00 AM
I did JJ's mod and it was still failing but not ending up in memory.

Commented out this section in the WM_CREATE,

;         .if frameCount > 1
;             
;             add frameNumber,1
;             
;             invoke getDelayForFrame,delayProp,frameNumber
;             invoke SetTimer,hWnd,123,eax,NULL
;             
;         .endif


And the Window appears with the gif image but of course no animation.

This is the ML command line in the batch file.

\masm32\bin\ml /c /coff /Zp8 "qword_gdip.asm"


I currently have ML version 14 running.
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 19, 2017, 02:33:56 AM
Quote from: hutch-- on May 19, 2017, 02:15:00 AM
I did JJ's mod and it was still failing but not ending up in memory.

Yes, sometimes it ends up in no man's land. But most of the time it works in Win10 with an xor esi, esi.
Title: Re: Viewing Animated GIF files
Post by: bluedevil on May 26, 2017, 10:33:17 PM
Hello everyone;

1. I also cannot managed to run on Win10x64. I am stuck like hutch--.
2. @jj2007, i attach my version on your codes please check it out. It is working, but not perfect. Try the other gif files in the zip package. If the gif file is rectangular or square, it is ok. But if it has some kinda transparent background, it show improperly. BTW jj2007 i admire your work on MasmBasic, i will spend on time with that. But my approach is more on reverse engineering so i want to learn winapi and masm/assembly much deeply.  On the contrary, masmbasic is really practical and very good if you develop or solve problems. But ineed deep understanding of the system.
3. So i will go an anigif library guys. If someone find a solution, i am here to listen.
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 26, 2017, 11:04:31 PM
Quote from: blue_devil on May 26, 2017, 10:33:17 PMIf the gif file is rectangular or square, it is ok. But if it has some kinda transparent background, it show improperly. BTW jj2007 i admire your work on MasmBasic

Thanks ;)

The size is not a factor afaik but the background is. Either add a timer event that forces an erase:
Event Timer
  GuiCls


Or load a non-transparent background GIF first:Event Paint
  GuiImage "Tweetie.gif", fit  ; not the best example, of course
  GuiImage "cross.gif", fit
GuiEnd


P.S.: It's actually easier to just add GuiCls (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1309):

include \masm32\MasmBasic\Res\MbGui.asm      ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)

Event Paint
  GuiCls            ; needed only for images with transparent background
  GuiImage "cross.gif", fit
GuiEnd


Tested OK on Win7-64, Win10-64, and my XP VM.
Title: Re: Viewing Animated GIF files
Post by: qWord on May 27, 2017, 02:33:17 AM
Quote from: blue_devil on May 26, 2017, 10:33:17 PM
1. I also cannot managed to run on Win10x64. I am stuck like hutch--.
yes, sorry for that. I've run it on an VM with Win10x64 and it did work (free running and in a Debugger). I've currently no access to a real installation, so no change to track that bug for me. You might insert some INT3's and step though the program using OllyDbg to see were it goes wrong.
JJ could jump in with showing his implementation, but he is unfortunately more interested in making people using his library  :(
Title: Re: Viewing Animated GIF files
Post by: RuiLoureiro on May 27, 2017, 04:16:39 AM
Hello qWord,
                   How are you ?
:icon14:
Title: Re: Viewing Animated GIF files
Post by: hutch-- on May 27, 2017, 05:53:50 AM
qword,

I can sympathise to this extent that code that has worked for years from XP and earlier needed to be changed for both Win7 64 and more recently Win10 64 so with code that I regularly use I build it in Win10 64 then back test it on Win7 and XP. So far with 64 bit MASM I have only developed on Win10 64 but so far it has all worked on Win7 64 so I don't have any problems there.
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 27, 2017, 06:37:58 AM
Hello, here is my version. Works in W7 64bits. Nevertheless I have noticed that the memory asigned to it grows each time you resize the window, surely it is any create_something that needs destroy it. I left it to the good reader  :bgrin:
Title: Re: Viewing Animated GIF files
Post by: bluedevil on May 27, 2017, 08:19:52 AM
Quote from: caballero on May 27, 2017, 06:37:58 AM
Hello, here is my version. Works in W7 64bits. Nevertheless I have noticed that the memory asigned to it grows each time you resize the window, surely it is any create_something that needs destroy it. I left it to the good reader  :bgrin:
Caballero thank you. I have compiled sources on Win7x86 and Win10x64 with old ML.exe. And they both worked on x86 and x64 virtual machines.
@qWord, today i worked on your sources and debuged them a lot but i couldn't find the differences that jj mentioned earlier. I xored the esi but nothing changed. And i also tried old ML and new ML.exe from Visual Studio :/

I am now preparing sources, when finished i will publish here.  8) And then i will come with new topic new sources and new questions :icon_redface: :idea:
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 27, 2017, 08:54:48 AM
Quote from: caballero on May 27, 2017, 06:37:58 AMthe memory asigned to it grows each time you resize the window

To test it, use SetTimer to call InvalidateRect, i.e. to trigger WM_PAINT events. After a while, Task Manager should show a trend.

The screenshot below shows the behaviour of an enlarged cross.gif (reply #20) after 55 minutes of cpu time. Looks quite ok, especially when compared to Firefox. Noteworthy: The working set starts at around 4.x MB and then increases steadily. This looks like a leak, but strangely enough, it stabilises after 10-20 minutes at 5.3 MB. I have no explanation for this behaviour. The page errors are also high in comparison to Firefox.

Your GDIPlusWM04.exe starts with a somewhat higher working set, but it remains remarkably stable when running - except when you resize the window, as you rightly noticed. What exactly do you do when the size changes?
Title: Re: Viewing Animated GIF files
Post by: bluedevil on May 27, 2017, 10:12:40 AM
@caballero
I want to ask some questions
1. You did define the path of the gif file by:
WSTR                szAnimGif, "Gangster.gif"
So why did you used WSTR macro, instead of defining directly

2. I wrote "FileOpen" function. By this function user can open any gif file s/he wants. Not a single one. So i need to change "szAnimGif" variable under my "FileOpen" funtion before calling your "prLoadAnimGif" function. I used lstrcpy but it didnt worked:
invoke lstrcpy, addr szAnimGif, addr ofn.lpstrFile
invoke    prLoadAnimGif

Any ideas?
Thanks.
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 27, 2017, 04:14:15 PM
1+2: Gdi+ needs the Unicode versions! Put an int 3 before the lstrcpy and launch Olly. Unless you are explicitly using the "W" version, i.e. GetOpenFileNameW, you have Ansi there.
Title: Re: Viewing Animated GIF files
Post by: newrobert on May 27, 2017, 06:02:25 PM
Olly,this software seems not to download.
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 27, 2017, 06:34:57 PM
Don't you sleep? :biggrin:

>use SetTimer to call InvalidateRect
I do it in this way

>What exactly do you do when the size changes?
It is in the code. With regarding to gdi+:
* I create a gdi+bitmap
* I create a gdi+double_buffer
Previously I delete both, otherwise the size of the program will increase without stop. Unfortunately, its size grows even if you reduce the size of the screen. I imagine it must create something internally that we are not destroying previously.

Another possibility is to make it in gdi (not +). One day, when I have time.

Edited: Now you can choose another gif file pressing the "1" button.
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 27, 2017, 08:07:05 PM
Is there no way to change the attached zip file when editing the post? ::)

Well, a fixed version for an small issue on the string filter for opening a file.
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 27, 2017, 08:23:10 PM
Quote from: newrobert on May 27, 2017, 06:02:25 PM
Olly,this software seems not to download.

Just tested, it works: direct link to zip file (http://www.ollydbg.de/odbg201.zip).

Quote from: caballero on May 27, 2017, 08:07:05 PM
Is there no way to change the attached zip file when editing the post? ::)

Shouldn't be a problem. Just uncheck the current attachment, then add a new one. It is a good idea to use a new name for the new attachment, as either browsers or the SMF software may give users the old cached one if you use the same name again.

Re leaks, here is what I get with some diagnostic code added:** line 195, GdipGraphicsClear                InvalidParameter
** line 196, GdipDrawImageRectI               InvalidParameter
** line 202, GdipDrawImagePointRectI          InvalidParameter
** line 301, GdipDeleteGraphics               ObjectBusy
...
** line 301, GdipDeleteGraphics               ObjectBusy
** line 272, GdipFree                         GenericError


The line 301 error appears every time when you resize the window. And as soon as you put the correct call there, all is fine with the working set, no more leak ;)

Apologies that this requires MasmBasic :bgrin:
Open the *.asc in RichMasm and hit F6. Press Ctrl G to insert the line number. I have changed only
- a handful of lines on top,
- gsi->Gsi because of a name conflict,
- invoke Gdi** -> invGdip Gdi**
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 27, 2017, 10:21:48 PM
No, I'm not able to change the f**cking file. Well, it is good to read the docs :lol: better use "GdipDisposeImage" for delete the gdi+ bitmap than "GdipDeleteGraphics" :greenclp:

Well, here it is the new working version. Now the mem size decreases when the window is aminorated. Nevertheless I have noticed that it size increases with no reason when the gif is changed. :icon_rolleyes:
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 27, 2017, 10:28:13 PM
Quote from: caballero on May 27, 2017, 10:21:48 PM
Well, it is good to read the docs :lol: better use "GdipDisposeImage"

Yes, RTFM is always a good idea. But it's much easier if you know that the culprit is GdipDeleteGraphics in line 301 :P

You still have 3*InvalidParameter to solve, but these calls are apparently not necessary.
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 27, 2017, 11:53:43 PM
> I have noticed that it size increases with no reason when the gif is changed.
For that, it is convenient to erase the objects before loading the new gif, as we have done in the resize section. With that it gets quite accurate. I left it to the good reader :t
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 29, 2017, 02:02:17 AM
Hello. A revision of the animated gif viewer with gdi+. This enhanced version work well with all the compilers: fasm, masm, nasmx, PellesC and TinyC for win32 and win64. Now transparent gifs do not blur the background. Besides now you can open any other gif than the default one, bearing in mind that need to use unicode chars for that.
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 29, 2017, 02:18:06 AM
It works fine now, but I see big differences between your display and mine. Is it the smoothing?

Attached an example - drag the tweety over ImageInfo.exe to see my version, press "0" in GDIPlusWM01.exe to open the GIF.

P.S.: Another odd thing is that the gangster appears far too small on launch, i.e. I have to resize the window to see it properly. In contrast, the tweety appears with the correct size.
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 29, 2017, 02:23:27 AM
I only get the error "Error leyendo gif" twice
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 29, 2017, 02:25:25 AM
Even if you extract all three files to the same folder and launch the exe from there?

Oops, I forgot that it expects gangster.gif there, too; this is your original code with the hard-coded path.

- re size of Gangster: you get the correct values, but Windows imposes a minimum width for the main window (your code is OK)
- I got an "unknown error" for the two GdipAlloc calls, but your code is OK: MSDN is wrong (https://msdn.microsoft.com/en-us/library/windows/desktop/ms534045(v=vs.85).aspx), GdipAlloc does not return a GpStatus but rather a pointer.
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 29, 2017, 02:28:34 AM
I execute yours and it seems to works fine

Well, there's some blur at the the right and bottom borders that dissapears after a while. Do you mean this? How did you do the double buffer and cleaning it?
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 29, 2017, 03:03:50 AM
Quote from: caballero on May 29, 2017, 02:28:34 AMWell, there's some blur at the the right and bottom borders that dissapears after a while.

Yes, but that's a different phenomenon. The blur comes from using \Masm32\MasmBasic\Res\MbBackground.gif as a background image, i.e. for "cleaning"; this is a 1 pixel image, and apparently when stretching to full size, Gdi+ plays little smoothing games :(

The outcome looks different with a "bigger" background, like the attached beach.jpg; unfortunately, this makes also come out the little defects in the tweety gif. Pretty odd behaviour.

Another solution is a GuiCls in the paint handler (which just paints the default main window background). See the difference in attachment. Note all three exes check the folder for all kind of images, you can scroll through them with the left and right keys (and rotate them with R and L, but that's irrelevant here).
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 29, 2017, 04:00:30 AM
I create a double buffering in memGraphics and clean it with GdipGraphicsClear.
Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 29, 2017, 04:02:43 AM
GdipGraphicsClear sounds like a good idea. May I steal it from you?  ;)
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 29, 2017, 05:07:21 AM
It's not my property :P
Title: Re: Viewing Animated GIF files
Post by: bluedevil on May 31, 2017, 01:54:50 AM
Hello;
I have edit the sources caballero had shared. Bu i am stuck again. Ok here are the issues:

1. I have add a "Close" menu item. I want to close the working Gif and want to see a blank window. I have tried several of thse commands but neither of them worked:
.elseif eax == IDM_FILE_CLOSE
;invoke KillTimer, [hWnd], cdIdTimer
        ;invoke GdipDisposeImage, [hGraphics]
        ;invoke GdipFree, [pPropertyItem]
        ;invoke GdipDeleteGraphics, [memGraphics]
        ;invoke GdipDeleteGraphics, [hGraphics]
        ;invoke UpdateWindow,hWin


2. I have added a "Open" menu item and also an accelerator for it. But it only works for one time like yours caballero. When i click open again -i mean call "FileOpen" again- OpenFile dialog doesn't recognize the gif file. I debugged it. So the problem is when i call ofn OpenFilename Structure the PATH of the secondly opened file overwrites the szFilter variable. Unfortunately i couldn't managed to fixed this issue.

FileOpen Proc Uses EBX
;LOCAL ofn :OPENFILENAME


Invoke RtlZeroMemory,addr ofn,SizeOf ofn
mov ofn.lStructSize, sizeof OPENFILENAME
m2m ofn.hwndOwner, hWnd
m2m ofn.hInstance, hInstance
m2m ofn.lpstrFilter, offset szOfnFilter ;Our Unicode filter
;mov ofn.lpstrCustomFilter,
;mov ofn.nMaxCustFilter,
;mov ofn.nFilterIndex,
;lea eax, szFileName
mov ofn.lpstrFile, offset szAnimGif ;Our Unicode file path
mov ofn.nMaxFile, sizeof szAnimGif * 2;trying to alloc a big part
;mov ofn.lpstrFileTitle
;mov ofn.nMaxFileTitle
;invoke GetModuleFileName,NULL,offset szBuffer,MAX_PATH
;mov ofn.lpstrInitialDir,offset SzBuffer
mov ofn.lpstrTitle, offset szOpenGif ;Dosya aç diyaloğonun başlığı
mov ofn.Flags, OFN_EXPLORER OR OFN_FILEMUSTEXIST OR OFN_HIDEREADONLY OR OFN_PATHMUSTEXIST OR OFN_LONGNAMES
;mov ofn.nFileOffset
;mov ofn.nFileExtension
mov ofn.lpstrDefExt, NULL

invoke GetOpenFileNameW,addr ofn ;Show Open File Diolog
.if eax
;Close old File?
        invoke    GdipDeleteGraphics, [memGraphics]
        invoke    GdipDisposeImage, [hGraphics]
        ;Load GIF
        invoke    prLoadAnimGif
        invoke    prGetGifSize
        invoke    SetMainWindowSize
        mov       dword ptr [nFramePosition], 0
        invoke    BeginPaint, [hWnd], offset ps
        invoke    prDrawFrameGif, eax
        invoke    EndPaint,[hWnd], offset ps
.EndIf

;invoke lstrcpyW,ofn.lpstrFile, chr$("hataoruBlueDevil.gif") ; itried interesting things but neigter of them worked
;m2m ofn.lpstrFilter, offset szOfnFilter
RET
FileOpen EndP


3. I also checked the macros asm because i want see that WSTR does. caballero you define a szAnimGif widestring like "blahblaf.GIF". It works first time. But when we try to open something new, szAnimGif turns like "C:\dir\anotherDir\maybeOneMoreDir\andFancy.Gif". At the end this variable overwrites our filter variable.

4. I also discovered one more thing. I execute proggy on a flash usb. like F:\proggy.exe and no errors. because the path is small it didn't overwrite the filter.

5.Because szFilter is overwritten, we cant select them on the openfile dialog. But we can write the name of the gif file to the name edit. And when we enter it we can show our gif on our dialog

Thank you for everything

Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 31, 2017, 03:52:12 AM
No time to look in detail, but just one question: How does OPENFILENAME (Ansi) work together with GetOpenFileNameW?
Title: Re: Viewing Animated GIF files
Post by: avcaballero on May 31, 2017, 04:35:35 AM
You are right as ever, JJ, nevertheless, I don't see any difference between them

OPENFILENAMEW STRUCT
  lStructSize        DWORD      ?
  hwndOwner          DWORD      ?
  hInstance          DWORD      ?
  lpstrFilter        DWORD      ?
  lpstrCustomFilter  DWORD      ?
  nMaxCustFilter     DWORD      ?
  nFilterIndex       DWORD      ?
  lpstrFile          DWORD      ?
  nMaxFile           DWORD      ?
  lpstrFileTitle     DWORD      ?
  nMaxFileTitle      DWORD      ?
  lpstrInitialDir    DWORD      ?
  lpstrTitle         DWORD      ?
  Flags              DWORD      ?
  nFileOffset         WORD      ?
  nFileExtension      WORD      ?
  lpstrDefExt        DWORD      ?
  lCustData          DWORD      ?
  lpfnHook           DWORD      ?
  lpTemplateName     DWORD      ?
OPENFILENAMEW ENDS


OPENFILENAMEA STRUCT
  lStructSize        DWORD      ?
  hwndOwner          DWORD      ?
  hInstance          DWORD      ?
  lpstrFilter        DWORD      ?
  lpstrCustomFilter  DWORD      ?
  nMaxCustFilter     DWORD      ?
  nFilterIndex       DWORD      ?
  lpstrFile          DWORD      ?
  nMaxFile           DWORD      ?
  lpstrFileTitle     DWORD      ?
  nMaxFileTitle      DWORD      ?
  lpstrInitialDir    DWORD      ?
  lpstrTitle         DWORD      ?
  Flags              DWORD      ?
  nFileOffset         WORD      ?
  nFileExtension      WORD      ?
  lpstrDefExt        DWORD      ?
  lCustData          DWORD      ?
  lpfnHook           DWORD      ?
  lpTemplateName     DWORD      ?
OPENFILENAMEA ENDS


> BlueDevil
1. Which OS are you using?
2. Do you have the latest version?
3. Neither of nasmx, fasm, masm, tinyc or pellesc works to you? All of them works to me in my W7-64 and WXP-32

I experimented the same issue in one of the first versions, that's why I allocated szAnimGif at the end of the data.  You can try to change
    mov       ofn.nMaxFile,MAXSIZE          ; Indicamos el tamaño máximo del fichero
by:
    mov       ofn.nMaxFile,MAXSIZE/2          ; Indicamos el tamaño máximo del fichero

By some reason fullfil the buffer with stuff though it does not come to mind

Try to value MAXSIZE       equ  600  (instead 300, for example)

Title: Re: Viewing Animated GIF files
Post by: jj2007 on May 31, 2017, 04:50:59 AM
Quote from: caballero on May 31, 2017, 04:35:35 AM
You are right as ever, JJ, nevertheless, I don't see any difference between them

You are right indeed - they are identical. I thought there was some fixed size buffer inside it, wrong idea :icon_redface:

P.S.: I have tried for an hour now to chase the GetOpenFileNameW bug, no luck. All I can say is that there is heap corruption - but no heap involved there ::)

Attached a version that works. There is still a problem with the heap, but at least you may understand why FileOpen crashed.