 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
ddk
Joined: 28 Dec 2009 Posts: 43
|
Posted: Wed Sep 01, 2010 7:15 pm Post subject: |
|
|
| What the heck really? After reinstall of windows none of the machine code functions hasn't worked. I've fresh install of AHK + AHK_L and none of Bin2Hex / Hex2Bin functions presented on this topic haven't worked at all. It always returns empty. At the moment I have ANSI build of AHK_L (version 1.0.48.05.L56). Could my nLited XP be the issue? Have I removed something important library? |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1786
|
Posted: Fri Sep 03, 2010 2:35 pm Post subject: |
|
|
Sorry, am I being dumb, but why doesnt the following work?
| Code: | double Test(double N1)
{
double N2 = 3;
return N1*N2;
} |
| Code: | MCode(r, "DD442404DC0D00000000C3")
E := DllCall(&r, "double", 2.0, "cdecl double")
MsgBox, %E% |
|
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Fri Sep 03, 2010 4:30 pm Post subject: |
|
|
just guessing... Operations on doubles are often performed by calling system functions. Their addresses are filled in by the linker. The machine code does not contain the system function, nor its correct address.
If you want to operate on doubles, you often have to write assembler code. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1786
|
Posted: Sat Sep 04, 2010 1:23 pm Post subject: |
|
|
| Laszlo wrote: | just guessing... Operations on doubles are often performed by calling system functions. Their addresses are filled in by the linker. The machine code does not contain the system function, nor its correct address.
If you want to operate on doubles, you often have to write assembler code. |
Would you be able to show me an example? Ive tried and failed
I seem to be getting so many things that to me inexplicably do not work:
| Code: | int HalfOpacity(unsigned char * Bitmap, int w, int h, int Stride)
{
int o;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
o = (4*x)+(Stride*y);
Bitmap[3+o] = Bitmap[3+o]/2;
Bitmap[2+o] = Bitmap[2+o];
Bitmap[1+o] = Bitmap[1+o];
Bitmap[o] = Bitmap[o];
}
}
return 0;
} |
The above code never reaches the end. Bitmap[3+o]/2 should cast it as an integer, so just to be sure, I did:
| Code: | int HalfOpacity(unsigned char * Bitmap, int w, int h, int Stride)
{
int o, p;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
o = (4*x)+(Stride*y);
p = Bitmap[3+o]/2;
Bitmap[3+o] = p;
Bitmap[2+o] = Bitmap[2+o];
Bitmap[1+o] = Bitmap[1+o];
Bitmap[o] = Bitmap[o];
}
}
return p;
} |
and it seems to do it correctly as it turns the opacity from 255 to 127....however, the code doesnt seem to actually do anything! The resulting bitmap is unchanged.
Its been giving me a real headache......youll notice that im doing Bitmap[o] = Bitmap[o];
so im assigning the blue value to itself....so i should be able to miss all of those lines out and just set opacity.....no such luck
This doesnt work:
| Code: |
int HalfOpacity(unsigned char * Bitmap, int w, int h, int Stride)
{
int o;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
o = (4*x)+(Stride*y);
Bitmap[3+o] = 127;
}
}
return 0;
} |
and this does:
| Code: | int HalfOpacity(unsigned char * Bitmap, int w, int h, int Stride)
{
int o;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
o = (4*x)+(Stride*y);
Bitmap[3+o] = 127;
Bitmap[2+o] = Bitmap[2+o];
Bitmap[1+o] = Bitmap[1+o];
Bitmap[o] = Bitmap[o];
}
}
return 0;
} |
if anyone can shed some light on this and also the double problem then I would be grateful to gain some of my sanity back |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Sat Sep 04, 2010 4:14 pm Post subject: |
|
|
I am not sure what you want to achieve with the C function, but the index calculation looks suspicious. I would try something like this: | Code: | int HalfOpacity(unsigned char * Bitmap, int w, int h, int Stride)
{
int o, x, y;
for (y = 0; y < h; ++y)
{
for (x = 0; x < w; ++x)
{
o = 4*(x+Stride*w*y);
Bitmap[3+o] /= 2;
}
}
return 0;
} |
You can test it in AHK with | Code: | MCode(HalfOpacity,"558bec578b7d1085ff7e2b8b550c0faf551433c9c1e20256837d0c007e128b"
. "45088b750c8d440103d02883c0044e75f803ca4f75e35e33c05f5dc3")
w := 3, h := 4
VarSetCapacity(BitMap,4*w*h,255)
dllcall(&HalfOpacity, "UInt",&BitMap, "Short",w, "Short",h, "Short",1, "CDECL Short")
SetFormat Integer, HEX
Loop %h% {
i := A_Index-1
Loop %w% {
j := A_Index-1
t .= NumGet(BitMap,(i*w+j)*4) . "`t"
}
t .= "`n"
}
MsgBox %t%
MCode(ByRef code, hex) {
VarSetCapacity(code, StrLen(hex)//2)
Loop % StrLen(hex)//2
NumPut("0x" . SubStr(hex, 2*A_Index-1, 2), code, A_Index-1, "char")
} |
You may need to swap the role of x and y in some places, make the C function "void", etc. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1786
|
Posted: Sat Sep 04, 2010 6:10 pm Post subject: |
|
|
Hey Laszlo
No the index calculations are definitely correct. You can see this in this example:
Gdip_PixelateBitmap.zip
Just run Gdip_PixelateBitmap.ahk and prepare to be amazed
| Code: | | o = (4*x)+(Stride*y); |
4 is for 32bpp (ARGB) and x is how many pixels along to move. Stride is the total width of a line of pixels including padding, so Stride*y will jump to the next row of pixels.
The above machine code for MCode_PixelateBitmap() is created from:
| Code: | int Gdip_PixelateBitmap(unsigned char * Bitmap, int w, int h, int Stride, int Size)
{
int sA, sR, sG, sB, rw, rh, o;
if (Size > w || Size > h)
Size = (w > h) ? h : w;
for (int y1 = 0; y1 < h/Size; ++y1)
{
for (int x1 = 0; x1 < w/Size; ++x1)
{
sA = sR = sG = sB = 0;
for (int y2 = 0; y2 < Size; ++y2)
{
for (int x2 = 0; x2 < Size; ++x2)
{
o = 4*(x2+x1*Size)+Stride*(y2+y1*Size);
sA += Bitmap[3+o];
sR += Bitmap[2+o];
sG += Bitmap[1+o];
sB += Bitmap[o];
}
}
sA /= Size*Size;
sR /= Size*Size;
sG /= Size*Size;
sB /= Size*Size;
for (int y2 = 0; y2 < Size; ++y2)
{
for (int x2 = 0; x2 < Size; ++x2)
{
o = 4*(x2+x1*Size)+Stride*(y2+y1*Size);
Bitmap[3+o] = sA;
Bitmap[2+o] = sR;
Bitmap[1+o] = sG;
Bitmap[o] = sB;
}
}
}
if (w % Size != 0)
{
sA = sR = sG = sB = 0;
for (int y2 = 0; y2 < Size; ++y2)
{
for (int x2 = 0; x2 < w % Size; ++x2)
{
o = 4*(x2+(w/Size)*Size)+Stride*(y2+y1*Size);
sA += Bitmap[3+o];
sR += Bitmap[2+o];
sG += Bitmap[1+o];
sB += Bitmap[o];
}
}
sA /= (w % Size)*Size;
sR /= (w % Size)*Size;
sG /= (w % Size)*Size;
sB /= (w % Size)*Size;
for (int y2 = 0; y2 < Size; ++y2)
{
for (int x2 = 0; x2 < w % Size; ++x2)
{
o = 4*(x2+(w/Size)*Size)+Stride*(y2+y1*Size);
Bitmap[3+o] = sA;
Bitmap[2+o] = sR;
Bitmap[1+o] = sG;
Bitmap[o] = sB;
}
}
}
}
for (int x1 = 0; x1 < w/Size; ++x1)
{
sA = sR = sG = sB = 0;
for (int y2 = 0; y2 < h % Size; ++y2)
{
for (int x2 = 0; x2 < Size; ++x2)
{
o = 4*(x2+x1*Size)+Stride*(y2+(h/Size)*Size);
sA += Bitmap[3+o];
sR += Bitmap[2+o];
sG += Bitmap[1+o];
sB += Bitmap[o];
}
}
sA /= Size*(h % Size);
sR /= Size*(h % Size);
sG /= Size*(h % Size);
sB /= Size*(h % Size);
for (int y2 = 0; y2 < h % Size; ++y2)
{
for (int x2 = 0; x2 < Size; ++x2)
{
o = 4*(x2+x1*Size)+Stride*(y2+(h/Size)*Size);
Bitmap[3+o] = sA;
Bitmap[2+o] = sR;
Bitmap[1+o] = sG;
Bitmap[o] = sB;
}
}
}
sA = sR = sG = sB = 0;
for (int y2 = 0; y2 < h % Size; ++y2)
{
for (int x2 = 0; x2 < w % Size; ++x2)
{
o = 4*(x2+(w/Size)*Size)+Stride*(y2+(h/Size)*Size);
sA += Bitmap[3+o];
sR += Bitmap[2+o];
sG += Bitmap[1+o];
sB += Bitmap[o];
}
}
sA /= (w % Size)*(h % Size);
sR /= (w % Size)*(h % Size);
sG /= (w % Size)*(h % Size);
sB /= (w % Size)*(h % Size);
for (int y2 = 0; y2 < h % Size; ++y2)
{
for (int x2 = 0; x2 < w % Size; ++x2)
{
o = 4*(x2+(w/Size)*Size)+Stride*(y2+(h/Size)*Size);
Bitmap[3+o] = sA;
Bitmap[2+o] = sR;
Bitmap[1+o] = sG;
Bitmap[o] = sB;
}
}
return 0;
} |
I will release this as the next Gdip tutorial (Gdip.ahk 1.38 is included in the zip)
So.....its so frustrating when some things just dont work and I have no idea why. there doesnt appear to be any reason for it  |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Sat Sep 04, 2010 7:16 pm Post subject: |
|
|
| What exactly does not work? Could you post the dll call, too? My sample code works for me with VS'08 express. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1786
|
Posted: Sat Sep 04, 2010 7:53 pm Post subject: |
|
|
ok so here is the full code of a very simple test of what Im trying (obviously the function isnt just going to half the opacity of a bitmap, but ive simplified it down to that as that is whats failing)
| Code: | int HalfOpacity(unsigned char * Bitmap, int w, int h, int Stride)
{
int o;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
o = (4*x)+(Stride*y);
Bitmap[3+o] = Bitmap[3+o]/2; //A
}
}
return 0;
} |
Bitmap[3+o] is A
Bitmap[2+o] is R
Bitmap[1+o] is G
Bitmap[3+o] is B
The project with above machine code is here:
http://www.autohotkey.net/~tic/HalfOpacity.zip
It will display the jpg on screen, but the machine code hasnt modified it all
however, this will work:
| Code: | int HalfOpacity(unsigned char * Bitmap, int w, int h, int Stride)
{
int o;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
o = (4*x)+(Stride*y);
Bitmap[3+o] = Bitmap[3+o]-127; //A
Bitmap[2+o] = Bitmap[2+o]; //R
Bitmap[1+o] = Bitmap[1+o]; //G
Bitmap[o] = Bitmap[o]; //B
}
}
return 0;
} |
This will also work:
| Code: | int HalfOpacity(unsigned char * Bitmap, int w, int h, int Stride)
{
int o;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
o = (4*x)+(Stride*y);
Bitmap[3+o] = Bitmap[3+o]-127; //A
Bitmap[2+o] = Bitmap[2+o]; //R
Bitmap[1+o] = Bitmap[1+o]; //G
}
}
return 0;
} |
but this wont:
| Code: | int HalfOpacity(unsigned char * Bitmap, int w, int h, int Stride)
{
int o;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
o = (4*x)+(Stride*y);
Bitmap[3+o] = Bitmap[3+o]-127; //A
Bitmap[2+o] = Bitmap[2+o]; //R
}
}
return 0;
} |
if you msgbox the return value then it gives no result, so its failed
Thanks for helping with this |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Sat Sep 04, 2010 8:23 pm Post subject: |
|
|
What AHK script do you use to call these? Try to strip it to the minimum, so the debugging could be easier.
In your large script you pass parameters as "int", but some C compilers use int as 16-bit integers. This is why I used in my AHK sample "short" parameters. Or use "long" in the C code...
Last edited by Laszlo on Sat Sep 04, 2010 8:27 pm; edited 1 time in total |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1786
|
Posted: Sat Sep 04, 2010 8:26 pm Post subject: |
|
|
| Laszlo wrote: | | What AHK script do you use to call these? Try to strip it to the minimum, so the debugging could be easier. |
its in the zip i attached along with the image it uses and the latest gdi+ library |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Sat Sep 04, 2010 8:29 pm Post subject: |
|
|
| In your script you pass parameters as "int", but some C compilers use int as 16-bit integers. This is why I used in my AHK sample "short" parameters. Or use "long" in the C code... Make sure the operands are of the same type. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1786
|
Posted: Sat Sep 04, 2010 8:34 pm Post subject: |
|
|
| Laszlo wrote: | | In your script you pass parameters as "int", but some C compilers use int as 16-bit integers. This is why I used in my AHK sample "short" parameters. Or use "long" in the C code... Make sure the operands are of the same type. |
i have tested that and it also does not work. also, that would not explain why some examples work fine, but if i remove some code then it stops working. the w and h parameters work fine and loop the correct number of times. try the Gdip_PixelateBitmap example and you can see that the same maths works fine |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Sat Sep 04, 2010 8:43 pm Post subject: |
|
|
| The next thing to check would be the machine code conversion. Sometimes the function code does not end at the return instruction. The example I posted above worked for me with any of your dummy instructions. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Sun Sep 05, 2010 1:41 am Post subject: |
|
|
| ddk wrote: | | What the heck really? After reinstall of windows none of the machine code functions hasn't worked. | I would guess that Data Execution Prevention got enabled. Try this:
| Code: | MCode(ByRef code, hex) {
VarSetCapacity(code,StrLen(hex)//2)
Loop % StrLen(hex)//2
NumPut("0x" . SubStr(hex,2*A_Index-1,2), code, A_Index-1, "Char")
DllCall("VirtualProtect", "uint", &code, "uint", VarSetCapacity(code), "uint", 0x40, "uint*", 0)
} |
| tic wrote: | | Sorry, am I being dumb, but why doesnt the following work? | How did you generate that code? It doesn't seem to actually correspond to your C source code. In particular, it has a hard-coded NULL pointer:
| Code: | DD 44 24 04 fld qword ptr [esp+4]
DC 0D 00 00 00 00 fmul qword ptr ds:[0]
C3 ret | This should be the address of a double-precision floating-point number (3.0). To use it with MCode, you would need to calculate the address at run-time and overwrite that part of the machine code. Most (or all?) floating-point operations don't accept their operand directly, only via a memory operand or the floating-point stack.
For integer factors, I would suggest something like this instead:
| Code: | DD 44 24 04 fld qword ptr [esp+4] ; load param onto FP stack => ST(0)
6A 03 push 3 ; push integer onto stack => [esp]
DA 0C 24 fimul dword ptr [esp] ; multiply ST(0) by [esp] (integer promoted to double)
59 pop ecx ; pop integer and discard
C3 ret
| Floating-point factors are a little more complicated. Here's an example:
| Code: | DD 44 24 04 fld qword ptr [esp+4]
68 00 00 0C 40 push 0x400C0000 ; push second half of (double)3.5
6A 00 push 0x00000000 ; push first half
DC 0C 24 fmul qword ptr [esp]
83 C4 08 add esp, 8
C3 ret
| Note that push 0 can also be encoded as 68 00 00 00 00. |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1786
|
Posted: Sun Sep 05, 2010 11:16 am Post subject: |
|
|
youre absolutely right Lex....
| Code: | | DD4424046A03DA0C2459C3 |
works perfectly from:
| Code: | DD 44 24 04 fld qword ptr [esp+4] ; load param onto FP stack => ST(0)
6A 03 push 3 ; push integer onto stack => [esp]
DA 0C 24 fimul dword ptr [esp] ; multiply ST(0) by [esp] (integer promoted to double)
59 pop ecx ; pop integer and discard
C3 ret |
Im confused why my machine code is wrong
I compile with flags:
/TC /c /FAc /Facode.cod /O2 /W1
to generate machine and assebly code with /FAc and get:
| Code: | ; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01
TITLE J:\My Dropbox\MCodeCreator\tempCode.c
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
PUBLIC __real@4008000000000000
PUBLIC _Test
EXTRN __fltused:DWORD
; COMDAT __real@4008000000000000
; File j:\my dropbox\mcodecreator\tempcode.c
CONST SEGMENT
__real@4008000000000000 DQ 04008000000000000r ; 3
; Function compile flags: /Ogtpy
CONST ENDS
; COMDAT _Test
_TEXT SEGMENT
_N1$ = 8 ; size = 8
_Test PROC ; COMDAT
; Line 4
00000 dd 44 24 04 fld QWORD PTR _N1$[esp-4]
00004 dc 0d 00 00 00
00 fmul QWORD PTR __real@4008000000000000
; Line 5
0000a c3 ret 0
_Test ENDP
_TEXT ENDS
END
|
what is:
| Code: | | QWORD PTR __real@4008000000000000 | ? |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|