Sign in to follow this  
Followers 0
crashdemons

GUICtrlSetImage Freeze

5 posts in this topic

#1 ·  Posted (edited)

Recently I have been working on a project that downloads Yahoo! display images as GIF (87a) and displays them on a Pic control. (since GUICtrlSetImage seems to support GIF)

This is all good and fine until I noticed that sometimes Yahoo! returns corrupt images - these corrupt images cannot be viewed by MSPaint (errors out) or GIMP (errors out) or Windows Fax/Image Viewer (Cannot be displayed) but CAN be viewed with Firefox (no errors) and Internet Explorer 7 (no errors)

BUT, the biggest problem is if you try to use the image as the source image for the Pic control using GUICtrlSetImage, the entire program will freeze indefinitely.

Here is an example GIF image (taken from when my program froze), zipped (so that image preview doesn't take effect)

Here is an example script that sets the image to a Pic control (have the above image in the same folder)

Tell me if you think of anyway to *repair* or *detect* before-hand that the image is corrupt; am pulling my hair out trying to figure out how to keep the script from freezing.

NOTE: This was in Au3.2.10 so if an update fixed this I must have misread the changelog

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Share this post


Link to post
Share on other sites



It appears that the files are not downloading completely; the end of file isn't being written properly.

So, I would guess the downloaded file isn't the same size as the file posted on the download site.

Can you use InetGetSize() before downloading and then use FileGetSize() after to do a comparison?

Should work unless the files corrupted on the server...

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

The HTTP response doesn't contain a "content-length" header (probably because they're sending the image over PHP);

so there's nothing to compare the filesize against.

Here's the basically what I was using to download the images.

$DI_Imagef=@ScriptDir&'\_DisplayTmp.gif'
$size='large'
$Username='bob'; originally read from a control on my GUI

;place the username, urlencoded, where %s is in the URL,  
$ImageURL=StringFormat('http://img.msg.yahoo.com/avatar.php?yids=%s&format=gif&size='&$size,__URLEncode($Username))
If InetGet($ImageURL,$DI_Imagef,1,1)=1 Then
        While @InetGetActive
            Sleep(500)
; the image loads quick enough that I don't want to measure the download - I just have other operations going on elsewhere that doesn't need blocked.
        WEnd
EndIf

Note: Don't worry about where I got __URLEncode - that should be easy enough to track down.

(and yes it's working fine)

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Share this post


Link to post
Share on other sites

OK, so here's a function that will check the last 2 bytes of a gif to check for a proper(?) EOF marker.

As far as I can tell, GIFs end with the hex characters of "00" and "3B" (null and a semicolon).

This makes use of a slightly modified version of zorphnog's _FileReadTail() function

#include <WinApi.au3>;required for _ReadFileTail() function

$gifName = "_DisplayTmp.gif"

$GifEOF = _ReadFileTail($gifName, 2);(gif filename,  number of bytes to read from tail)

If $GifEOF = "003B" Then
    MsgBox(0, "", "Gif is OK")
Else
    MsgBox(16, "", "Gif is Corrupt")
EndIf

Func _ReadFileTail($sInFilename, $nBytes)
;slight modified version of zorphnog's function at: 
;   http://www.autoitscript.com/forum/index.php?s=&showtopic=74775&view=findpost&p=544151

    Local $hInFile, $aResult, $hBuffer, $nRead

; Open file for reading
    $hInFile = _WinAPI_CreateFile($sInFilename, 2, 2, 2)
    If $hInFile = 0 Then
        ConsoleWrite("!> [" & _WinAPI_GetLastError() & "] " & _WinAPI_GetLastErrorMessage() & @LF)
        Return
    EndIf

; Move file pointer to desired position
    $aResult = DllCall("Kernel32.dll", "dword", "SetFilePointer", "hwnd", $hInFile, "int", Int("-" & $nBytes), "long_ptr", 0, "dword", 2)
    $nPosition = $aResult[0]
    $nOffset = Int("0x" & StringRight(Hex($nPosition), 1))
    $nPosition -= $nOffset

; Create file read buffer
    $hBuffer = DllStructCreate("ubyte buffer[" & $nBytes & "]")
    $pBuffer = DllStructGetPtr($hBuffer)

    If _WinAPI_ReadFile($hInFile, $pBuffer, $nBytes, $nRead) Then
        $sBuffer = StringTrimLeft(DllStructGetData($hBuffer, "buffer"), 2)
        For $i = 0 To ($nRead / 16) + 1
            $sHex = ""
            $sWord = ""
            If $sBuffer = "" Then ExitLoop
            $sTemp = StringLeft($sBuffer, 32 - ($nOffset * 2))
            $sBuffer = StringTrimLeft($sBuffer, 32 - ($nOffset * 2))
            For $j = $nOffset To 15
                $sHex &= StringLeft($sTemp, 2)
                If Mod($j, 2) = 1 Then $sHex &= " "
                $nCode = Int("0x" & StringLeft($sTemp, 2))
                If $nCode > 31 And $nCode < 127 Then
                    $sWord &= Chr($nCode)
                Else
                    $sWord &= "."
                EndIf
                $sTemp = StringTrimLeft($sTemp, 2)
                If $sTemp = "" Then ExitLoop
            Next
            If $i = 0 Then $nOffset = 0
            $nPosition += 32
        Next
        _WinAPI_CloseHandle($hInFile)
        Return StringTrimLeft(DllStructGetData($hBuffer, "buffer"), 2)
    Else
        ConsoleWrite("!> [" & _WinAPI_GetLastError() & "] " & _WinAPI_GetLastErrorMessage() & @CRLF)
        SetError(1, 0, 0)
        _WinAPI_CloseHandle($hInFile)
        Return
    EndIf
EndFunc  ;==>_ReadFileTail

Share this post


Link to post
Share on other sites

Try to use GDI+ for load image/draw image. Maybe it will help as workaround.

Search:

_WinAPI_GetDC()

_WinAPI_CreateCompatibleBitmap()

_GDIPlus_ImageLoadFromFile()

_GDIPlus_GraphicsDrawImageRect()

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0