Sign in to follow this  
Followers 0

Snippet Dump

120 posts in this topic

Posted (edited)

Am I missing something? Isn't that the same script I posted except with the extra AscW function? Where's the error in the first post, because the output is identical.

Look more closely - I also added two extra lines to your function. The test you ran does not contain any surrogates, so it only appeared to be working.

Edited by czardas

Share this post


Link to post
Share on other sites



Posted

Ah I see it now, I forgot the extra lines which make it skip the characters if there's a surrogate.

Share this post


Link to post
Share on other sites

Posted (edited)

Only a short while ago I knew nothing about surrogates, I found the example in the following link very informative and easy to follow. http://zsigri.tripod.com/fontboard/cjk/surrog.html

In the following thread trancexx showed me a neat trick:

I decided to try and reverse the process.

Local $sTestChar = _ChrW(108246)
MsgBox(0, "", _AscW($sTestChar))

Func _AscW($sChar) ; By czardas
    Local $sLen = StringLen($sChar)
    If $sLen = 1 Then Return AscW($sChar)
    If $sLen = 0 Or $sLen > 2 Then Return SetError(1, 0, "") ; Invalid string length
    Local $iSur_Lo = AscW(StringLeft($sChar, 1)), $iSur_Hi = AscW(StringRight($sChar, 1))
    If $iSur_Lo < 0xD800 Or $iSur_Lo > 0xDBFF Or $iSur_Hi < 0xDC00 Or $iSur_Hi > 0xDFFF Then  Return SetError(2, 0, "") ; Invalid pair sequence
    Return BitOr(BitShift(BitXOR($iSur_Lo , 0xD800), -10), BitXOR($iSur_Hi, 0xDC00), 0x10000)
EndFunc

Func _ChrW($iCodePoint) ; By trancexx
    If $iCodePoint <= 0xFFFF Then Return ChrW($iCodePoint)
    If $iCodePoint > 0x10FFFF Then Return SetError(1, 0, "")
    Local $tOut = DllStructCreate("word[2]")
    DllStructSetData($tOut, 1, BitShift($iCodePoint, 10) + 0xD7C0, 1)
    DllStructSetData($tOut, 1, BitAND($iCodePoint, 0x3FF) + 0xDC00, 2)
    Return BinaryToString(DllStructGetData(DllStructCreate("byte[4]", DllStructGetPtr($tOut)), 1), 2)
EndFunc
Edited by czardas

Share this post


Link to post
Share on other sites

Posted (edited)

Please Note : Many of the functions in this thread have been organised into several UDFs found at the following link:

I find managing updates and code changes easier this way. Modal.au3 will no longer be supported. Details of the changes will be added to the relevant posts in due course. I feel have learned a lot since I started this thread, and I thank all those who have contributed.

Edited by czardas

Share this post


Link to post
Share on other sites

Posted (edited)

Loaded Dice

The default number of sides is 6. The default load parameter is 2. This means the dice is twice as likely to roll a large number than a small number. If the load equals 1, then the dice rolls without any preference. If the load is 0.25, there is a 1 in 4 chance of rolling a high number etc...

Func _LoadedDice($iSides = 6, $fLoad = 2)
    If Not IsInt($iSides) Or $iSides < 1 Then Return SetError(1, 0, 0)

    If $fLoad < 0 Then $fLoad = 1/$fLoad ; Negative weight is interpreted as a fraction
    $fLoad *= $fLoad ; It doesn't work correctly without this
    Local $iReturn = Ceiling(Log(_Random(1, $fLoad))*$iSides/Log($fLoad)) ; The magic happens here

    If $iReturn < 1 Or $iReturn > $iSides Then ; Possible float output limitation
        If Round($fLoad) = 0 Or $iSides = 1 Then
            $iReturn = 1
        ElseIf Round($fLoad) = 1 Then
            $iReturn = Random(1, $iSides, 1)
        Else
            Return SetError(2, 0, 0) ; Debugging Mysterious error
        EndIf
    EndIf
    Return $iReturn
EndFunc

Func _Random($nNum1 = 0, $nNum2 = 1, $iFlag = 0)
    Local $nReturn = $nNum1
    If $nNum1 < $nNum2 Then
        $nReturn = Random($nNum1, $nNum2, $iFlag)
    ElseIf $nNum1 > $nNum2 Then
        $nReturn = Random($nNum2, $nNum1, $iFlag)
    EndIf
    If @error Then Return SetError(1, 0, 0)
    Return $nReturn
EndFunc
Edited by czardas

Share this post


Link to post
Share on other sites

Posted (edited)

FileIsImage()

Checks if a file is an image or not. Perhaps someone might make use of it. Please report any false positives, or give suggestions if you can see ways to improve this function. Thanks.

;

Func _FileIsImage($sFilePath)
    Local $aImageSignature[27] = _
    ["424D", _ ; BMP, DIB
    "492049", _ ; TIFF- 'I I' >>look for Nul
    "FFD8FFE0", _ ; JPG, JPEG, JPE
    "FFD8FFE1", _
    "FFD8FFE8", _
    "FFD8FFE2", _
    "FFD8FFE3", _
    "FF575043", _ ; WPG
    "EB3C902A", _ ; IMG
    "C5D0D3C6", _ ; EPS
    "7E424B00", _ ; PSP
    "D7CDC69A", _ ; WMF
    "0A020101", _ ; PCX
    "0A030101", _
    "0A050101", _
    "49492A00", _ ; TIFF, TIF
    "4D4D002A", _
    "4D4D002B", _
    "38425053", _ ; PSD
    "504943540008", _ ; IMG
    "01DA01010003", _ ; RGB
    "474946383761", _ ; GIF - GIF87a
    "474946383961", _ ;     - GIF89a
    "0000000C6A502020", _ ; JP2
    "89504E470D0A1A0A", _ ; PNG
    "252150532D41646F", _ ; EPS
    "737263646F636964"] ; CAL

    Local $dBinary, $iFileSize, $dTest, $hFile = FileOpen($sFilePath, 16)
    If $hFile = -1 Then Return SetError(1, 0, "")

    $dBinary = FileRead($hFile, 8)
    If @error Then
        FileClose($hFile)
        Return SetError(2, 0, "")
    EndIf
    FileClose($hFile)
    $dBinary = StringTrimLeft($dBinary, 2) ; Remove prefix

    If StringLeft($dBinary, 4) = $aImageSignature[0] Then ; Possibly Bitmap
        $dTest = ""
        $iFileSize = Hex(FileGetSize($sFilePath))
        For $i = 8 To 2 Step -2
            $dTest &= StringMid($iFileSize, $i -1, 2)
        Next
        Return $dTest = StringMid($dBinary, 5, 8)

    ElseIf StringLeft($dBinary, 6) = $aImageSignature[1] Then ; Could be a TIF
        For $i = 7 To 15 Step 2
            If StringMid($dBinary, $i, 2) = "00" Then Return True ; Definately not a txt file
        Next
        Return False
    EndIf

    $dTest = StringLeft($dBinary, 8)
    For $i = 2 To 17
        If $dTest = $aImageSignature[$i] Then Return True ; JPG, JPEG, JPE, WPG, IMG, EPS, PSP, WMF, PCX
    Next

    If $dTest = $aImageSignature[18] Then
        For $i = 9 To 15 Step 2
            If StringMid($dBinary, $i, 2) = "00" Or _
            StringMid($dBinary, $i, 2) = "01" Then Return True ; Should find a version number 01
        Next
        Return False
    EndIf

    $dTest = StringLeft($dBinary, 12)
    If $dTest = $aImageSignature[19] Or $dTest = $aImageSignature[20] Then Return True ; IMG, RGB

    For $i = 23 To 26
        If $dBinary = $aImageSignature[$i] Then Return True ; JP2, PNG, EPS, CAL
    Next

    If $dTest = $aImageSignature[21] Or $dTest = $aImageSignature[22] Then ; Maybe GIF
        $hFile = FileOpen($sFilePath, 16)
        $dTest = FileRead($hFile)
        FileClose($hFile)

        Return StringRight($dTest, 2) = "3B"
    EndIf

    Return False
EndFunc ;==> _FileIsImage
Edited by czardas

Share this post


Link to post
Share on other sites

Posted (edited)

Here a snippet using GDI+ to get information about an image but it's limited to GDI+ supported images only:

 

#include <GDIPlus.au3>

Global $sFile = FileOpenDialog("Select an image", "", "(*.jpg;*.png;*.bmp;*.gif;*.tif;*.ico;*.emf;*.wmf)")
If @error Then Exit

_GDIPlus_Startup()
Global $aResult = _GDIPlus_ImageGetInfo($sFile)
If @error Then Exit _GDIPlus_Shutdown()

MsgBox(0, "Image Information",  "Filename: " & $sFile & @LF & @LF & _
                                "Width: " & @TAB & @TAB & $aResult[0] & @LF & _
                                "Height: " & @TAB & @TAB & $aResult[1] & @LF & _
                                "DPI: " & @TAB & @TAB & $aResult[2] & "x" & $aResult[3] & @LF & _
                                "Color Depth: " & @TAB & $aResult[4]  & @LF & _
                                "Image Type: " & @TAB & $aResult[5], 30)
_GDIPlus_Shutdown()


Func _GDIPlus_ImageGetInfo($sFile) ;coded by UEZ 2013
    Local $hImage = _GDIPlus_ImageLoadFromFile($sFile)
    If Not $hImage Or @error Then Return SetError(1, 0, 0)
    Local $aPixelFormat = _GDIPlus_ImageGetPixelFormat($hImage)
    Local $aImageRawFormat = _GDIPlus_ImageGetRawFormat($hImage)
    Local $hImageContext = _GDIPlus_ImageGetGraphicsContext($hImage)
    Local $aImageDPIX = DllCall($ghGDIPDll, "uint", "GdipGetDpiX", "handle", $hImageContext, "float*", 0)
    Local $aImageDPIY = DllCall($ghGDIPDll, "uint", "GdipGetDpiY", "handle", $hImageContext, "float*", 0)
    _GDIPlus_GraphicsDispose($hImageContext)
    Local $aResult[6] = [   _GDIPlus_ImageGetWidth($hImage), _GDIPlus_ImageGetHeight($hImage), _
                            Round($aImageDPIX[2], 0), Round($aImageDPIY[2], 0), _
                            $aPixelFormat[1], $aImageRawFormat[1]]
    _GDIPlus_ImageDispose($hImage)
    Return $aResult
EndFunc

Br,

UEZ

Edited by UEZ

Share this post


Link to post
Share on other sites

Posted

Thanks UEZ. That's a nice snippet. It appears to work a treat. :)

Share this post


Link to post
Share on other sites

Posted (edited)

Dumping this here for future scrutiny. For usage see the following topic:

$avTarget - The target array to concatenate onto
$avSource - The source array to concatenate from
$iTargetBase - Is the target Array 0-base or 1-base index? 0-base by default
$iSourceBase - Is the source Array 0-base or 1-base index? 0-base by default
$iUniqueTarget - Is the target Array already unique? 0 by default
$iCaseSense - Case Sensitivity. 0 by default
$sDelimiter - Choose a different delimiter. '|' by default
$iDelimCheck - Set to 0 ONLY if you are certain the delimiter does not exist in any Array element

;

Func _ArrayUniqueConcatenate(ByRef $avTarget, ByRef $avSource, $iTargetBase = 0, $iSourceBase = 0, $iUniqueTarget = 0, $iCaseSense = 0, $sDelim = "|", $iDelimCheck = 1)
    If Not IsArray($avTarget) Or UBound($avTarget, 0) <> 1 Then Return SetError(1)
    If Not IsArray($avSource) Or UBound($avSource, 0) <> 1 Then Return SetError(2)

    Local $iBoundTarget = UBound($avTarget), $iBoundSource = UBound($avSource)
    If $iTargetBase Then $iTargetBase = 1
    If $iSourceBase Then $iSourceBase = 1

    If $iDelimCheck Then
        Local $s2ndDelim
        If $sDelim = ";" Then
            $s2ndDelim = "|"
        Else
            $s2ndDelim = ";"
        EndIf

        For $i = $iTargetBase To $iBoundTarget - 1
            While StringInStr($avTarget[$i], $sDelim)
                $sDelim &= $s2ndDelim
            WEnd
        Next

        For $i = $iSourceBase To $iBoundSource - 1
            While StringInStr($avSource[$i], $sDelim)
                $sDelim &= $s2ndDelim
            WEnd
        Next
    EndIf

    Local $sStringArray = $sDelim
    If $iUniqueTarget Then
        For $i = $iTargetBase To $iBoundTarget - 1
            $sStringArray &= $avTarget[$i] & $sDelim
        Next
    Else
        For $i = $iTargetBase To $iBoundTarget - 1
            If StringInStr($sStringArray, $sDelim & $avTarget[$i] & $sDelim, $iCaseSense) Then ContinueLoop
            $sStringArray &= $avTarget[$i] & $sDelim
        Next
    EndIf
    $avTarget = 0

    For $i = $iSourceBase To $iBoundSource - 1
        If StringInStr($sStringArray, $sDelim & $avSource[$i] & $sDelim, $iCaseSense) Then ContinueLoop
        $sStringArray &= $avSource[$i] & $sDelim
    Next

    Local $iLen = StringLen($sDelim)
    $sStringArray = StringTrimLeft(StringTrimRight($sStringArray, $iLen), $iLen)

    $avTarget = StringSplit($sStringArray, $sDelim, 1)

    Return $avTarget[0] +1 ; The size of the new array
EndFunc ;==> _ArrayUniqueConcatenate

;

The above function turns out to be much slower than the different approach linked to below. The differences still need investigating. It may be that the above function will churn through larger amounts of data at a regular but on average much slower speed. May also need more tweaking.

>Related Function

Edited by czardas

Share this post


Link to post
Share on other sites

Posted (edited)

RandomHexStr()

Create a random hex string of between 0 and 2147483647 characters. This can be used for a number of purposes - such as in testing other functions.

Not sure if This can be optimized any further.

MsgBox(0, "", _RandomHexStr(2^12)) ; Example

Func _RandomHexStr($iLen)
    Local $sHexString = ""
    For $i = 1 To Floor($iLen/7)
        $sHexString &= StringRight(Hex(Random(0, 0xFFFFFFF, 1)), 7)
    Next
    $sHexString &= StringRight(Hex(Random(0, 0xFFFFFFF, 1)), Mod($iLen, 7))
    Return $sHexString
EndFunc ;==> _RandomHexStr
Edited by czardas

Share this post


Link to post
Share on other sites

Posted

What is that function supposed to be doing, and what would you use it for?

Share this post


Link to post
Share on other sites

Posted

What is that function supposed to be doing, and what would you use it for?

 

Lot's of stuff really. I added a bit of a description. :)

Share this post


Link to post
Share on other sites

Posted

Beware that characters in AutoIt are UTF16-LE encoded (actually restricted to UCS-2 but it seems that genuine UTF16 strings are fine even if the surrogate machinery is not at work here). That means that your "blind" randomizing will produce invalid sequences. Also Unicode is limited to 0x000000 to 0x10FFFF (UTF16 can't represent more than 17 planes of 64K codepoints), most of this range being unassigned or reserved for private use.

Share this post


Link to post
Share on other sites

Posted (edited)

And like jchd I would like to say that the mnemonics behind the opcodes that you create mostly don't even exist in x86 assembly.

Edited by trancexx

Share this post


Link to post
Share on other sites

Posted (edited)

Thanks jchd and trancexx for the detailed feedback. Of course I'm aware that there will be invalid sequences for unicode. You may have noticed I used it though. Results on some of my tests will be out some. A general random binary string has to be exactly that. If it can't be interpreted is that really some kind of problem. I don't see why.

Edited by czardas

Share this post


Link to post
Share on other sites

Posted

Ha, if it's for binary only use, then this white noise is good enough.  I don't know why I was relating this the the long filename thread and discussion(s). Myopia + age(*) are killing me slowly but surely.

(*) also this moth**erfu**er Labtec mini keyboard I should have thrown away months ago.

Share this post


Link to post
Share on other sites

Posted (edited)

Well indeed. It is actually just a noise generator. I didn't actually think of it like that. I have only used it a couple of times myself.

Edited by czardas

Share this post


Link to post
Share on other sites

Posted

Regarding your modified _ArrayUniqueConcatenate function.

I wonder if the new way in beta that you can access array elements, means you can query an array in an array without first copying it.

Just thinking aloud.

Share this post


Link to post
Share on other sites

Posted (edited)

Regarding your modified _ArrayUniqueConcatenate function.

I wonder if the new way in beta that you can access array elements, means you can query an array in an array without first copying it.

Just thinking aloud.

 

I'm not sure. I prefer to use multidimensional arrays over arrays within arrays, but I could try it out. The affect on performance may be of less significant than other factors.  The method is somewhat experimental.

Edited by czardas

Share this post


Link to post
Share on other sites

Posted (edited)

Array_Search_All_Dimensions()

_Array_Search_All_Dimensions searches through an array of up to 16 dimensions. There are only 3 parameters.

1st param = Array to search.

2nd param = The string to search for

3rd [optional] param = Case sensitivity, Default = 0 (not case sensitive)

The returned array of matches contains indices from each dimension separated by a comma.

;

Func _Array_Search_All_Dimensions(ByRef $aArray, $vFind, $iCasesense = 0)
    #forceref $vFind
    If Not IsArray($aArray) Then Return SetError(1, 0, 0)

    Local $aBound[17] = [UBound($aArray, 0),0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    If $aBound[0] > 16 Then Return SetError(2, 0, 0) ; Only 16 dimensions are supported
    For $i = 1 To $aBound[0]
        $aBound[$i] = UBound($aArray, $i) -1
    Next

    Local $sExpression = "$aArray" & StringLeft("[$0][$1][$2][$3][$4][$5][$6][$7][$8][$9][$a][$b][$c][$d][$e][$f]", $aBound[0] *4)
    If $iCasesense Then $sExpression &= "="
    $sExpression &= "=$vFind"

    Local $sElements = "", $sPosition = StringLeft("$0&','&$1&','&$2&','&$3&','&$4&','&$5&','&$6&','&$7&','&$8&','&$9&','&$a&','&$b&','&$c&','&$d&','&$e&','&$f", $aBound[0]*7 -5)
    For $f = 0 To $aBound[16]
        For $e = 0 To $aBound[15]
            For $d = 0 To $aBound[14]
                For $c = 0 To $aBound[13]
                    For $b = 0 To $aBound[12]
                        For $a = 0 To $aBound[11]
                            For $9 = 0 To $aBound[10]
                                For $8 = 0 To $aBound[9]
                                    For $7 = 0 To $aBound[8]
                                        For $6 = 0 To $aBound[7]
                                            For $5 = 0 To $aBound[6]
                                                For $4 = 0 To $aBound[5]
                                                    For $3 = 0 To $aBound[4]
                                                        For $2 = 0 To $aBound[3]
                                                            For $1 = 0 To $aBound[2]
                                                                For $0 = 0 To $aBound[1]
                                                                    If Execute($sExpression) Then $sElements &= Execute($sPosition) & "|"
                                                                Next
                                                            Next
                                                        Next
                                                    Next
                                                Next
                                            Next
                                        Next
                                    Next
                                Next
                            Next
                        Next
                    Next
                Next
            Next
        Next
    Next
    $sElements = StringTrimRight($sElements, 1)

    Local $aResults[1] = [0]
    If $sElements Then $aResults = StringSplit($sElements, "|")
    Return $aResults
EndFunc

;

Below is an example of searching through an eight dimensional array with 362880 elements filled with random data. The search is repeated twice: each time with varied parameters. It takes a few seconds on each run - watch the SciTE console.

;

#include <Array.au3>

ConsoleWrite("Creating array" & @LF)
Local $a_Eight_Dimensions[4][8][2][3][9][6][7][5], _ ; Contains 362880 array elements
$aSwitch[2] = ["_RandomHexStr(Random(0, 3, 1))", "StringLower(_RandomHexStr(Random(0, 3, 1)))"]

For $0 = 0 To 3 ; Adding data to $a_Eight_Dimensions
    For $1 = 0 To 7
        For $2 = 0 To 1
            For $3 = 0 To 2
                For $4 = 0 To 8
                    For $5 = 0 To 5
                        For $6 = 0 To 6
                            For $7 = 0 To 4
                                $a_Eight_Dimensions[$0][$1][$2][$3][$4][$5][$6][$7] = Execute($aSwitch[Random(0, 1, 1)])
                            Next
                        Next
                    Next
                Next
            Next
        Next
    Next
Next

Local $aRet1, $aRet2, $aRet3, $iTimer
ConsoleWrite("Starting Timer" & @LF)

$iTimer = TimerInit()
$aRet1 = _Array_Search_All_Dimensions($a_Eight_Dimensions, "ABC")
ConsoleWrite("Seconds = " & TimerDiff($iTimer)/1000 & @LF)
_ArrayDisplay($aRet1, "ABC / abc")

$iTimer = TimerInit()
$aRet2 = _Array_Search_All_Dimensions($a_Eight_Dimensions, "abc", 1)
ConsoleWrite("Seconds = " & TimerDiff($iTimer)/1000 & @LF)
_ArrayDisplay($aRet2, "abc")

$iTimer = TimerInit()
$aRet3 = _Array_Search_All_Dimensions($a_Eight_Dimensions, "ABC", 1)
ConsoleWrite("Seconds = " & TimerDiff($iTimer)/1000 & @LF)
_ArrayDisplay($aRet3, "ABC")

ConsoleWrite("$aRet1[0] = $aRet2[0] + $aRet3[0] . . . " & ($aRet1[0] = $aRet2[0] + $aRet3[0]) & @LF)

Func _RandomHexStr($iLen)
    Local $sHexString = ""
    For $i = 1 To Floor($iLen/7)
        $sHexString &= StringRight(Hex(Random(0, 0xFFFFFFF, 1)), 7)
    Next
    Return $sHexString & StringRight(Hex(Random(0, 0xFFFFFFF, 1)), Mod($iLen, 7))
EndFunc ;==> _RandomHexStr

Func _Array_Search_All_Dimensions(ByRef $aArray, $vFind, $iCasesense = 0)
    #forceref $vFind
    If Not IsArray($aArray) Then Return SetError(1, 0, 0)

    Local $aBound[17] = [UBound($aArray, 0),0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    If $aBound[0] > 16 Then Return SetError(2, 0, 0) ; Only 16 dimensions are supported
    For $i = 1 To $aBound[0]
        $aBound[$i] = UBound($aArray, $i) -1
    Next

    Local $sExpression = "$aArray" & StringLeft("[$0][$1][$2][$3][$4][$5][$6][$7][$8][$9][$a][$b][$c][$d][$e][$f]", $aBound[0] *4)
    If $iCasesense Then $sExpression &= "="
    $sExpression &= "=$vFind"

    Local $sElements = "", $sPosition = StringLeft("$0&','&$1&','&$2&','&$3&','&$4&','&$5&','&$6&','&$7&','&$8&','&$9&','&$a&','&$b&','&$c&','&$d&','&$e&','&$f", $aBound[0]*7 -5)
    For $f = 0 To $aBound[16]
        For $e = 0 To $aBound[15]
            For $d = 0 To $aBound[14]
                For $c = 0 To $aBound[13]
                    For $b = 0 To $aBound[12]
                        For $a = 0 To $aBound[11]
                            For $9 = 0 To $aBound[10]
                                For $8 = 0 To $aBound[9]
                                    For $7 = 0 To $aBound[8]
                                        For $6 = 0 To $aBound[7]
                                            For $5 = 0 To $aBound[6]
                                                For $4 = 0 To $aBound[5]
                                                    For $3 = 0 To $aBound[4]
                                                        For $2 = 0 To $aBound[3]
                                                            For $1 = 0 To $aBound[2]
                                                                For $0 = 0 To $aBound[1]
                                                                    If Execute($sExpression) Then $sElements &= Execute($sPosition) & "|"
                                                                Next
                                                            Next
                                                        Next
                                                    Next
                                                Next
                                            Next
                                        Next
                                    Next
                                Next
                            Next
                        Next
                    Next
                Next
            Next
        Next
    Next
    $sElements = StringTrimRight($sElements, 1)

    Local $aResults[1] = [0]
    If $sElements Then $aResults = StringSplit($sElements, "|")
    Return $aResults
EndFunc

;

Functions posted in this thread will be documented fully later - if selected to become part of a UDF.

Edited by czardas

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