Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include ImagePut.ahk
- ImagePut.gdiplusStartup()
- pBitmap1 := ImagePut("Bitmap", "xd.png")
- pBitmap2 := ImagePut("Bitmap", "x2.png")
- pBitmap3 := ImagePut("Bitmap", "x3.png")
- pBitmap4 := ImagePut("Bitmap", "x4.png")
- errors := 0
- Loop 100000 {
- QPC(1)
- isBitmapEqual1(pBitmap1, pBitmap2)
- old += QPC()
- QPC(1)
- isBitmapEqual2(pBitmap1, pBitmap2)
- new += QPC()
- }
- ImagePut.DisposeImage(pBitmap1)
- ImagePut.DisposeImage(pBitmap2)
- ImagePut.DisposeImage(pBitmap3)
- ImagePut.DisposeImage(pBitmap4)
- if (old > new)
- winner := "New Version wins by " old - new " and is " Abs(old - new)/new*100 "% faster."
- else
- winner := "Old Version wins by " new - old " and is " Abs(old - new)/old*100 "% faster."
- MsgBox % "Control:`t`t" control "`nOld Version:`t" old "`nNew Version:`t" new "`n" winner
- MsgBox % "Number of errors:`t" errors
- return
- Esc:: ExitApp
- isBitmapEqual1(ByRef pBitmap1, ByRef pBitmap2, Format := 0x26200A) {
- ; Make sure both bitmaps are valid pointers.
- if !(pBitmap1 && pBitmap2)
- return false
- ; Check if pointers are identical.
- if (pBitmap1 == pBitmap2)
- return true
- ; The two bitmaps must be the same size.
- DllCall("gdiplus\GdipGetImageWidth", "ptr", pBitmap1, "uint*", Width1)
- DllCall("gdiplus\GdipGetImageWidth", "ptr", pBitmap2, "uint*", Width2)
- DllCall("gdiplus\GdipGetImageHeight", "ptr", pBitmap1, "uint*", Height1)
- DllCall("gdiplus\GdipGetImageHeight", "ptr", pBitmap2, "uint*", Height2)
- ; Match bitmap dimensions.
- if (Width1 != Width2 || Height1 != Height2)
- return false
- ; Create a RECT with the width and height and two empty BitmapData.
- VarSetCapacity(Rect, 16, 0) ; sizeof(Rect) = 16
- , NumPut( Width1, Rect, 8, "uint") ; Width
- , NumPut( Height1, Rect, 12, "uint") ; Height
- VarSetCapacity(BitmapData1, 16+2*A_PtrSize, 0) ; sizeof(BitmapData) = 24, 32
- VarSetCapacity(BitmapData2, 16+2*A_PtrSize, 0) ; sizeof(BitmapData) = 24, 32
- ; Transfer the pixels to a read-only buffer. Avoid using a different PixelFormat.
- DllCall("gdiplus\GdipBitmapLockBits"
- , "ptr", pBitmap1
- , "ptr", &Rect
- , "uint", 1 ; ImageLockMode.ReadOnly
- , "int", Format ; Format32bppArgb is fast.
- , "ptr", &BitmapData1)
- DllCall("gdiplus\GdipBitmapLockBits"
- , "ptr", pBitmap2
- , "ptr", &Rect
- , "uint", 1 ; ImageLockMode.ReadOnly
- , "int", Format ; Format32bppArgb is fast.
- , "ptr", &BitmapData2)
- ; Get Stride (number of bytes per horizontal line) and two pointers.
- Stride := NumGet(BitmapData1, 8, "int")
- Scan01 := NumGet(BitmapData1, 16, "ptr")
- Scan02 := NumGet(BitmapData2, 16, "ptr")
- ; RtlCompareMemory preforms an unsafe comparison stopping at the first different byte.
- size := Stride * Height1
- byte := DllCall("ntdll\RtlCompareMemory", "ptr", Scan01+0, "ptr", Scan02+0, "uptr", size, "uptr")
- ; Cleanup
- DllCall("gdiplus\GdipBitmapUnlockBits", "ptr", pBitmap1, "ptr", &BitmapData1)
- DllCall("gdiplus\GdipBitmapUnlockBits", "ptr", pBitmap2, "ptr", &BitmapData2)
- return (byte == size) ? true : false
- }
- isBitmapEqual2(ByRef pBitmap1, ByRef pBitmap2, Format := 0x26200A) {
- ; Make sure both bitmaps are valid pointers.
- if !(pBitmap1 && pBitmap2)
- return false
- ; Check if pointers are identical.
- if (pBitmap1 == pBitmap2)
- return true
- ; The two bitmaps must be the same size.
- DllCall("gdiplus\GdipGetImageWidth", "ptr", pBitmap1, "uint*", Width1)
- DllCall("gdiplus\GdipGetImageWidth", "ptr", pBitmap2, "uint*", Width2)
- DllCall("gdiplus\GdipGetImageHeight", "ptr", pBitmap1, "uint*", Height1)
- DllCall("gdiplus\GdipGetImageHeight", "ptr", pBitmap2, "uint*", Height2)
- ; Match bitmap dimensions.
- if (Width1 != Width2 || Height1 != Height2)
- return false
- ; Create a RECT with the width and height and two empty BitmapData.
- VarSetCapacity(Rect, 16, 0) ; sizeof(Rect) = 16
- , NumPut( Width1, Rect, 8, "uint") ; Width
- , NumPut( Height1, Rect, 12, "uint") ; Height
- ; Do this twice.
- while ((i++:=i?i:0) < 2) { ; for(int i = 0; i < 2; i++)
- ; Create a BitmapData structure.
- VarSetCapacity(BitmapData%i%, 16+2*A_PtrSize, 0) ; sizeof(BitmapData) = 24, 32
- ; Transfer the pixels to a read-only buffer. Avoid using a different PixelFormat.
- DllCall("gdiplus\GdipBitmapLockBits"
- , "ptr", pBitmap%i%
- , "ptr", &Rect
- , "uint", 1 ; ImageLockMode.ReadOnly
- , "int", Format ; Format32bppArgb is fast.
- , "ptr", &BitmapData%i%)
- ; Get Stride (number of bytes per horizontal line).
- Stride%i% := NumGet(BitmapData%i%, 8, "int")
- ; If the Stride is negative, clone the image to make it top-down; redo the loop.
- if (Stride%i% < 0) {
- DllCall("gdiplus\GdipCloneImage", "ptr", pBitmap%i%, "ptr*", pBitmapClone)
- DllCall("gdiplus\GdipDisposeImage", "ptr", pBitmap%i%) ; Permanently deletes.
- pBitmap%i% := pBitmapClone
- i--
- }
- ; Get Scan0 (top-left first pixel)
- Scan0%i% := NumGet(BitmapData%i%, 16, "ptr")
- }
- ; RtlCompareMemory preforms an unsafe comparison stopping at the first different byte.
- size := Stride1 * Height1
- byte := DllCall("ntdll\RtlCompareMemory", "ptr", Scan01+0, "ptr", Scan02+0, "uptr", size, "uptr")
- ; Cleanup
- DllCall("gdiplus\GdipBitmapUnlockBits", "ptr", pBitmap1, "ptr", &BitmapData1)
- DllCall("gdiplus\GdipBitmapUnlockBits", "ptr", pBitmap2, "ptr", &BitmapData2)
- return (byte == size) ? true : false
- }
- QPC( R := 0 ) { ; By SKAN, http://goo.gl/nf7O4G, CD:01/Sep/2014 | MD:01/Sep/2014
- Static P := 0, F := 0, Q := DllCall( "QueryPerformanceFrequency", "Int64P",F )
- Return ! DllCall( "QueryPerformanceCounter","Int64P",Q ) + ( R ? (P:=Q)/F : (Q-P)/F )
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement