
EddieBoy
Active Members-
Posts
40 -
Joined
-
Last visited
EddieBoy's Achievements

Seeker (1/7)
1
Reputation
-
Most efficient ways to handle binary?
EddieBoy replied to EddieBoy's topic in AutoIt General Help and Support
Wow, being able to run assembly from within Autoit would be extremely useful for some types of processing. If I'm understanding the Binary.au3 by Ward, it seems to forward assembly-code snippets along with arguments to Windows DLLs for processing; similarly FLAT.DLL lets you build assembly code in memory and run it from there. I'm speculating that Binary.au3 involves a fair amount of overhead since it creates a new copy of the assembly-code each time it's run, whereas FLAT uses a pointer to the assembly-code location thus letting it be reused without generating a new copy. That may be completely wrong. I will have to do some studying to get up to speed, but this knowledge will be very helpful. Thank you both for your tips and patience -
Most efficient ways to handle binary?
EddieBoy replied to EddieBoy's topic in AutoIt General Help and Support
Processing is much faster for binary images thanks to RTFC LarsJ. I'm still a bit perplexed by limitations. For example, the function below converts a 16bit image in xBGR order into 24bit RGB. It takes about 2 seconds to process a small 300x300 image. In assembly, it would take a fraction of a second. The biggest slowdown seems to come from the DLLStructSetData() which is run 3 times per pixel to store the converted color values to their new structure. This was necessary to extract 1 byte from the 4byte long values. I know all numbers are 32bit to a 32bit processor, but at the assembly level, you use a command like 'store byte' to quickly discard the upper 24bits. Is there a faster way 'extract' and merge single bytes from multiple 32bit values? BinaryMid() is painfully slow. Func _16to24(ByRef $BMPimage) ;BMPimage = structure with 16bit image data Local $pointer, $size, $NewBMPimage, $count = 1 ;calculate number of 2byte blocks (aka pixel count) $size = DllStructGetSize($BMPimage) / 2 ;get pointer to image location $pointer = DllStructGetPtr($BMPimage) ;define new structure sized for 2byte (1pixel) processing $temp = DllStructCreate('USHORT [' & $size & ']', $pointer) ;define new structure for 24bit image (3bytes per pixel) $NewBMPimage = DllStructCreate('ubyte image[' & $size * 3 & ']') ;convert 1 pixel per loop from 16bit tBGR > RGB 24bit For $i = 1 To $size ;Get 1 pixel $2byte = DllStructGetData($temp, 1, $i) ;extract 5bit colorchannels, convert to 8bit, then store in new structure DllStructSetData($NewBMPimage, 1, BitShift($2byte, 10) * 8.22, $count) ;blue DllStructSetData($NewBMPimage, 1, BitShift(BitShift($2byte, -22), 27) * 8.22, $count + 1) ;green DllStructSetData($NewBMPimage, 1, BitAND(0x001F, $2byte) * 8.22, $count + 2) ;red $count += 3 Next ;clear unneeded structures $temp = 0 $BMPimage = 0 Return $NewBMPimage EndFunc -
Most efficient ways to handle binary?
EddieBoy replied to EddieBoy's topic in AutoIt General Help and Support
Thank you, I will check that out. I am actually a relative beginner; I just went about learning in a strange backwards way. My experience with MIPS based assembly language came from doing fan translations of old console games. That required doing things like adding support for variable width English fonts at the assembly level. I only started to dig into high level programming later. Because high level programming is far more abstract than assembly, I find it generally harder to learn, but easier to use. -
Most efficient ways to handle binary?
EddieBoy replied to EddieBoy's topic in AutoIt General Help and Support
Thank you both very much. I'll study those tutorials. My old coding methods where taking a couple seconds just to do something simple like flip an image. This will be a huge help! EDIT: A quote from the tutorial PDF linked by RTFC: I've handled assembly language a fair bit and this is exactly what I was missing when using Autoit. It also highlights the usefulness of the code Larsj provided. Thank you both so much- this opens whole new ways to process binary files. -
Most efficient ways to handle binary?
EddieBoy replied to EddieBoy's topic in AutoIt General Help and Support
Edited my question (above) to be more concise. For other boobs...I mean noobs like me who are trying to optimize their code, Here's a link to the AU3Profiler tool which I found extremely helpful: https://www.autoitscript.com/forum/topic/106811-au3profiler/ -
Most of the tools I make with Autoit handle data of the binary type, but I don't know efficient ways to process binary in Autoit. EDITED to simplify: Can anyone point me toward a tutorial on how to manipulate binary data efficiently in Autoit? Specifically, I need to read an entire binary file (such as a photo) into a variable, then have the ability to efficiently split and edit portions of the binary as needed. I get the impression that DllStructCreate is the area I should be looking at, but trying to comprehend the helpfile on this topic (which is 70% alien programmer-isms) is daunting since I'm not even sure that's the right track. I'm a relative beginner, and just a hobbyist so sorry if I'm asking a stupid question.
-
Forgive me for necro-posting, but my issue applies directly to the code here. I'm working on an image converter that outputs BMPs and ran into an issue. BMPs read image data in 4byte chunks (word) so they require padding at the end of each pixel line to bring the width up to a multiple of 4. The included code to do this is: Local $c=Mod($Width,4) Local $d=Binary("") if $c=3 then $d=Binary("0x000000") if $c=2 then $d=Binary("0x0000") if $c=1 then $d=Binary("0x00") But isn't that reversed? If for example, the width was 15, it would require 1 byte padding to reach 16 (aka multiple of 4). Mod(15) would return a remainder of 3, and thus the above code would attach 3 bytes padding instead of 1. Am I just being stupid and missing something obvious?
-
czardas reacted to a post in a topic: Hex ( ) conversion odd results
-
Hex ( ) conversion odd results
EddieBoy replied to EddieBoy's topic in AutoIt General Help and Support
Wow, thank you everyone for these insights. jchd: I was indeed misunderstand what IsFloat( ) and IsInt( ) did. Apparently they test the data in the variable rather that check the variable 'type'. So IsFloat will return false for floating point Type data, as long as that data is a whole number ie. IsFloat(1.00) = False. That explains one of the reasons I had trouble tracking this bug down . czardas : I went back and checked the function. My example left one 'addition' element out of the equation, and that element seems to be the issue: it's a hex value stored as "string" type that is read from a input field as such: $variable = "0x" & GuiCtrlRead($InputField) All the other variables involved test as Int32 but when the hex value in "string" format is included, Autoit outputs the product as a "double" type. At least now I can convert the string to a decimal as soon as it's read from the GUI. If I'm thinking right, that should at least shrink the array's size in RAM. Thanks everyone, the info here will be quite helpful! -
Hex ( ) conversion odd results
EddieBoy replied to EddieBoy's topic in AutoIt General Help and Support
Melba32 Thank you so much! I scoured the help file, yet somehow managed to miss VarGetType . The type is showing 'double' , which I would expect is the issue. I would be stretching it to call myself an intermediate programmer, but aren't doubles used for floating-point numbers, yet IsFloat () return False. The array number comes from a simple "For" loop, $count = 1... $count = $count+1 .... $count = $count * 4 ... $array[$i][0] = $count. Perhaps declaring the original variable type instead of leaving it to Autoit would help. I'll keep digging with this new info. Really appreciate the lead! UPDATE: using " Number($double,1) " fixed the issue (double to 32 bit integer conversion), but I'm still going to dig into why it was stored as a double so I can avoid the wasted conversion. A little research shows that a "double" does store 64 bits of floating point data, but isn't called "float" which exclusively stores 32bit floating point data. I expect that's why IsFloat returned False. Again, thanks much Melba! -
I've run into an issue with Hex( ). Basically, its returning a wonky 64bit value when asked to convert an integer well below the signed 32bit limit. If it makes a difference, my program pulls this value from an array and needs to convert it to hex before writing it to a txt file. The program scans a binary file for specific values, if it finds the value, enters it's location into an array, passes the array to this function which outputs the info to a text file. If I feed Hex() the same numbers directly, it works beautifully, so I'm not able to recreate this issue in a small code snippet. Hopefully a screen shot showing the problem will suffice. The $b variable is taken from an array (ie $b = $array[$i][0]). I've spent two days finding the source of this issue and looking for a solution with no luck. Any help is greatly appreciated!
-
I found that using Binary(FileRead($x)) with FileOpen($x) can cause failed reads (blank) on systems that use 2byte per letter text encoding. It's not clearly stated in the help file that the default mode for FileOpen() is text and should not be used to read binary data. Or, this may be a bug in Autoit. I in this example, $data should return "FF000000" through "C00000", but as you can see from my screen shot, it returns empty reads between FD and DF. This seems to happen on computers set to 2byte per letter text encodings. Local $data For $i = 1 to 0xff $data= Binary($i) & Binary($data) Next $file = FileOpen(@WorkingDir & "\.example_DELETE.txt",2) FileWrite($file, $data) FileSetPos($file,0,0) $data = "" For $i = 1 To 0xff $data = Binary($data) & Binary(FileRead($file,1)) Next MsgBox(0,"",$data) FileClose($file)
-
I thought your Dec(0x##,2) answer made sense Zedna, based on the "Dec()" description in the helpfile. Treating a hex value as 64 bit seems like it would remove the 32bit signed limit. I don't understand why it didn't seem to work, but I'm new to programming so there's a lot I don't understand My program is working with user input higher than 7fffffff set up like this: FileSetPos($BigFile, "0x" & GUICtrlRead($input), 0)
-
I tested more and found out it works if I put 0xab36a000 in quotes. As in: $x = FileOpen("test.bin") FileSetPos($x,"0xab36a000",0) MsgBox(0,"", FileGetPos($x)) FileClose($x) I guess Autoit handles hex differently when in quotes. In my program, this value (0xab36a000) comes from user input. I"ll do some tests and hopefully figure out how to get it working well. Thanks everyone!
-
Thanks for your help. I updated Autoit to v3.3.8.1, but it still won't set the file position when using a hex value above 0x7FFFFFFF Anything above Dec(0x7FFFFFFF,2) returns error (0). _WinAPI_SetFilePointer() sounds like it will work, but I'll have to rewrite my code some to fit it in. A sample, but it needs a "test.bin" larger than 0xab36a000: $x = FileOpen("test.bin") FileSetPos($x,0xab36a000,0) MsgBox(0,"", FileGetPos($x)) FileClose($x)