crashdemons Posted July 2, 2008 Share Posted July 2, 2008 (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 July 2, 2008 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.) Link to comment Share on other sites More sharing options...
ResNullius Posted July 2, 2008 Share Posted July 2, 2008 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... Link to comment Share on other sites More sharing options...
crashdemons Posted July 2, 2008 Author Share Posted July 2, 2008 (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 July 2, 2008 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.) Link to comment Share on other sites More sharing options...
ResNullius Posted July 2, 2008 Share Posted July 2, 2008 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 expandcollapse popup#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 Link to comment Share on other sites More sharing options...
Zedna Posted July 2, 2008 Share Posted July 2, 2008 Try to use GDI+ for load image/draw image. Maybe it will help as workaround. Search: _WinAPI_GetDC() _WinAPI_CreateCompatibleBitmap() _GDIPlus_ImageLoadFromFile() _GDIPlus_GraphicsDrawImageRect() Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now