Bitmap image processing with masm32 - image-processing
I am working with masm 32. I want to process bitmap images. But I don't know how to get an image or save an image.
I have no idea about processing images with masm.
Any information will help me.
Thanks
This might get you started... This is basic code to load in a bitmap and display it on a dialog box. I'm not sure what mean by 'processing' bitmap images, I suspect you need something more complex. However, this might get you started...
.386
.model flat,stdcall
option casemap:none
includelib user32.lib
includelib kernel32.lib
includelib shell32.lib
includelib comctl32.lib
includelib comdlg32.lib
includelib gdi32.lib
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
IDD_DIALOG equ 1000
IDC_BITMAP equ 100
IDM_MENU equ 10000
.const
ClassName db 'DLGCLASS',0
.data?
hInstance dd ?
CommandLine dd ?
hWnd dd ?
hBitmap dd ?
.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke GetCommandLine
invoke InitCommonControls
mov CommandLine,eax
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
mov wc.cbSize,sizeof WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc,offset WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,DLGWINDOWEXTRA
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName,offset ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx,addr wc
invoke CreateDialogParam,hInstance,IDD_DIALOG,NULL,addr WndProc,NULL
invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd
.while TRUE
invoke GetMessage,addr msg,NULL,0,0
.BREAK .if !eax
invoke TranslateMessage,addr msg
invoke DispatchMessage,addr msg
.endw
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL ps:PAINTSTRUCT
LOCAL hdc:HDC
LOCAL hMemDC:HDC
LOCAL rect:RECT
mov eax,uMsg
.if eax==WM_INITDIALOG
push hWin
pop hWnd
; Load up the bitmap
invoke LoadBitmap, hInstance, IDC_BITMAP
mov hBitmap, eax
.elseif eax==WM_COMMAND
mov eax,wParam
mov edx, eax
shr edx, 16
.if lParam==0
.if eax==IDM_FILE_EXIT
invoke SendMessage,hWin,WM_CLOSE,0,0
.elseif eax==IDM_HELP_ABOUT
invoke ShellAbout,hWin,addr AppName,addr AboutMsg,NULL
.endif
.else
.endif
.elseif eax==WM_PAINT
invoke BeginPaint, hWnd, addr ps
mov hdc, eax
invoke CreateCompatibleDC, hdc
mov hMemDC, eax
invoke SelectObject, hMemDC, hBitmap
invoke GetClientRect, hWnd, addr rect
invoke BitBlt, hdc, 10, 10, rect.right, rect.bottom, hMemDC, 0, 0, SRCAND
invoke DeleteDC, hMemDC
invoke EndPaint, hWnd, addr ps
.elseif eax==WM_CLOSE
invoke DestroyWindow,hWin
.elseif uMsg==WM_DESTROY
invoke DeleteObject, hBitmap
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
end start
Note the LoadBitmap API call and the WM_PAINT routine.
..Forgot the .rc file...
#define IDD_DIALOG 1000
#define IDC_BITMAP 100
IDC_BITMAP BITMAP DISCARDABLE "myfile.bmp"
Related
With an iOS quick action (shortcut item), what is the purpose of the completion handler parameter?
An iOS quick action / shortcut item is received by the app delegate's implementation of application(_:performActionFor:completionHandler:). In that implementation, you are supposed to call the completionHandler. It takes a Bool. Does anyone know what the Bool is for? I see no difference regardless of whether I pass true or false. (In fact, I see no difference even if I neglect to call the completionHandler!)
Short answer: parameter is not used in implementation of block in iOS 10 (guess that in iOS 9 too, but can't check right now). Long answer: let's see what happens inside of completion block: ___50-[UIApplication _handleApplicationShortcutAction:]_block_invoke: push rbp ; XREF=-[UIApplication _handleApplicationShortcutAction:]+132 mov rbp, rsp mov rax, qword [ds:rdi+0x20] mov rdx, qword [ds:rdi+0x28] mov rsi, qword [ds:0x1179e88] ; #selector(_updateSnapshotAndStateRestorationWithAction:) mov rdi, rax ; argument "instance" for method imp___got__objc_msgSend pop rbp jmp qword [ds:imp___got__objc_msgSend] ; endp I run this on Intel64, so first argument should be stored in rdi register (when we calling block under ARC it is an instance of NSMallocBlock). There is no selector, so second parameter (bool argument) should be stored in rsi register. But rsi register is not used in code - it just sends message _updateSnapshotAndStateRestorationWithAction: to object ds:rdi+0x20 with argument ds:rdi+0x28. Both ds:rdi+0x20 and ds:rdi+0x28 are captured pointers inside of the block. Think that the guess with parameter as indicator for snapshot function was wrong.
Compiling Pascalscript in 64 bit mode, events not working?
I have downloaded and started playing with Pascalscript and its sample programs. I have come across a problem with interfacing to Forms using the Forms access sample script. It works in 32 bit mode, in 64 bit mode no events get triggered. That is, a buttons onpress event never calls the pascalscript onpress code. I am using Delphi 10 Seattle on windows 7 pro. Any ideas on how to get scripts working right on the 64 bit platform?
Well seeing as no one had an answer to this I had to do the hard work myself. So the problem was empty prolog code for x64 in the conversion from delphi to pascalscript method calling which was written in assembler. The empty method handler was called "MyAllMethodhandler" in the uPSruntime unit and my code solution is as follows function MyAllMethodsHandler2(Self:PScriptMethodInfo; const Stack:PPointer; _EDX,_ECX:Pointer):Integer; forward; {$ifdef CPUX64} procedure MyAllMethodsHandler; // On entry: // RCX = Self pointer // RDX, R8, R9 = param1 .. param3 // STACK = param4... paramcount asm PUSH R9 MOV R9,R8 // R9:=_ECX MOV R8,RDX // R8:=_EDX MOV RDX, RSP // RDX:=Stack SUB RSP, 20h CALL MyAllMethodsHandler2 ADD RSP, 20h //Restore stack POP R9 end; {$else} procedure MyAllMethodsHandler; //original x86 code // On entry: // EAX = Self pointer // EDX, ECX = param1 and param2 // STACK = param3... paramcount asm push 0 push ecx push edx mov edx, esp add edx, 16 // was 12 pop ecx call MyAllMethodsHandler2 pop ecx mov edx, [esp] add esp, eax mov [esp], edx mov eax, ecx end; {$endif} Not sure if this will work with everything but seems to work for at least 2 parameters. I'll post it as a comment on GitHub, I can't really fix it directly as I have made extensive changes to the whole of Pascal script so it supports complex math.
Delphi 2010 - EDirectoryNotFoundException when trying to save logs
I'm developing a program in Delphi 2010 that has to save the logs that are stored in a Tmemo. I'm trying to create a log file for everyday in which I append the logs from a memo.After I append the text I clear the content of the memo. So in the location of my app i want to create a folder named "loguri-mover_ftp" in which i want to store the log file. EX: log_mover-ftp_2-16-2015.txt The code I use for this is: If DirectoryExists(ExtractFilePath(Application.ExeName) + 'loguri-mover_ftp') then begin TFile.AppendAllText(ExtractFilePath(Application.ExeName) + 'loguri-mover_ftp\log_mover-ftp_' + datetostr(now) + '.txt',memo_loguri.lines.text, TEncoding.UTF8); Memo_loguri.lines.text:=''; end else begin CreateDir(ExtractFilePath(Application.ExeName) + 'loguri-mover_ftp'); TFile.AppendAllText(ExtractFilePath(Application.ExeName) + 'loguri-mover_ftp\log_mover-ftp_' + datetostr(now) + '.txt',memo_loguri.lines.text, TEncoding.UTF8); Memo_loguri.lines.text:=''; end; Because I'm interested in the stability of my application I've enabled the MadExcept debugger inside my app. After 2 hours 12 minutes i get the following error: exception class : EDirectoryNotFoundException exception message : The specified path was not found. compiled with : Delphi 2010 program up time : 2 hours 12 minutes madExcept version : 4.0.7 callstack crc : $bed2c7c0, $c58f696b, $05cb237f count : 5 exception number : 1 disassembling: [...] 005ce40a push eax 005ce40b call -$13ee30 ($48f5e0) ; SysUtils.TEncoding.GetUTF8 005ce410 mov ecx, eax 005ce412 pop eax 005ce413 pop edx 005ce414 > call -$1144ad ($4b9f6c) ; IOUtils.TFile.AppendAllText 005ce419 775 mov eax, [ebp+8] 005ce41c mov eax, [eax+$2a0] 005ce422 xor edx, edx 005ce424 mov ecx, [eax] 005ce426 call dword ptr [ecx+$2c] [...] What am I doing wrong?
The exception is raised by the call to AppendAllText. If you follow the source for that function you will find a call to InternalCheckFilePathParam, the implementation of which looks like this: class procedure TFile.InternalCheckFilePathParam(const Path: string; const FileExistsCheck: Boolean); begin if (Length(Path) >= MAX_PATH - TFile.FCMinFileNameLen) and (not TPath.IsExtendedPrefixed(Path)) then raise EPathTooLongException.CreateRes(#SPathTooLong); if not TPath.HasPathValidColon(Path) then raise ENotSupportedException.CreateRes(#SPathFormatNotSupported); if Trim(Path) = '' then // DO NOT LOCALIZE raise EArgumentException.CreateRes(#SInvalidCharsInPath); if not TPath.HasValidPathChars(Path, False) then raise EArgumentException.CreateRes(#SInvalidCharsInPath); if not TDirectory.Exists(TPath.DoGetDirectoryName(TPath.DoGetFullPath(Path))) then raise EDirectoryNotFoundException.CreateRes(#SPathNotFound); if FileExistsCheck and (not Exists(Path)) then raise EFileNotFoundException.CreateRes(#SFileNotFound); end; Now, Path is the first argument that you passed to AppendAllText. Since EDirectoryNotFoundException is being raised, we can conclude that the directory containing Path does not exist. Of course, this seems odd give that you check for its existence and then create it. I think the mystery can be solved by looking at what datetostr(now) returns. You imagine that the date separator used is -. But what if the date separator is /? In that case the / will be interpreted as a path delimiter. The solution is to specify the date separator explicitly by using the DateToStr overload that accepts a TFormatSettings parameter. I also cannot ignore the duplication in your code. Please don't ever repeat magic strings the way you do. The code should look like this: LogFileDir := TPath.Combine(ExtractFilePath(Application.ExeName), 'loguri-mover_ftp'); if not DirectoryExists(LogFileDir) then ForceDirectories(LogFileDir); DateStr := DateToStr(Now, ...); // you supply an appropriate TFormatSettings LogFilePath := TPath.Combine(LogFileDir, log_mover-ftp_' + DateStr + '.txt'); TFile.AppendAllText(LogFilePath, memo_loguri.lines.text, TEncoding.UTF8);
MASM - HeapAlloc throws exception
I'm here again. I'm using masm .dll in c# application, but now my code throws 'System.AccessViolationException' in line: INVOKE HeapAlloc, edx, 0, <size> Can you tell me what cause problem? Here is my ASM code: invoke GetProcessHeap mov edx, eax INVOKE HeapAlloc, edx, 0, dlText mov tab, eax INVOKE HeapAlloc, edx, 0, dlText mov wynik, eax
I found the cause of error. I was using edx instead of ebx ;)
Delphi TPrinters.GetPrinters call hangs
I have an app that has returned an error report. The app is written in Delphi 2006 and hangs during startup. The MadExcept main thread stack is shown below. I suspect there is no default printer but I can't replicate the fault here. Anyone seen this problem? Initialization part of unit WWPrintToPrinterOrPDFRoutines initialization PagesRangeStartPage := 1 ; PagesRangeEndPage := 999 ; PrintRange := prAll ; PrintCopies := 1 ; PrintCollate := false ; InitialPrintPaperName := 'A4' ; if (Printer.Printers.Count = 0) then // <--------- this causes the hang begin InitialPrintOrientation := Printers.poPortrait ; end else begin InitialPrintOrientation := GetDefaultPrinterOrientation ; InitialPrintPaperName := GetDefaultPrinterPaperName ; end ; CurrentPreviewPage := 1 ; NDRMemoryStream := TMemoryStream.Create ; or disassembled: WWPrintToPrinterOrPDFRoutines.pas.682: PagesRangeStartPage := 1 ; 007C4404 C705EC8B81000100 mov [$00818bec],$00000001 WWPrintToPrinterOrPDFRoutines.pas.683: PagesRangeEndPage := 999 ; 007C440E C705F08B8100E703 mov [$00818bf0],$000003e7 WWPrintToPrinterOrPDFRoutines.pas.684: PrintRange := prAll ; 007C4418 C605F48B810001 mov byte ptr [$00818bf4],$01 WWPrintToPrinterOrPDFRoutines.pas.685: PrintCopies := 1 ; 007C441F C705F88B81000100 mov [$00818bf8],$00000001 WWPrintToPrinterOrPDFRoutines.pas.686: PrintCollate := false ; 007C4429 C605FC8B810000 mov byte ptr [$00818bfc],$00 WWPrintToPrinterOrPDFRoutines.pas.687: InitialPrintPaperName := 'A4' ; 007C4430 B8288C8100 mov eax,$00818c28 007C4435 BAC0447C00 mov edx,$007c44c0 007C443A E82D1AC4FF call #LStrAsg WWPrintToPrinterOrPDFRoutines.pas.689: if (Printer.Printers.Count = 0) then 007C443F E8B0BCCDFF call Printer 007C4444 E89FB7CDFF call TPrinter.GetPrinters <----- HANG OCCURS HERE
I don't think there is anything wrong with your program or anything you could change to make this not hang. Something is wrong on the OS level with that system. That NdrClientCall2 function is part of the Remote Procedure Call Network Data Representation Engine which is used for making RPC and DCOM calls. NtConnectPort is a function to connect a port object (that's a fundamental kernel object, like e.g. a mutex or a file handle). Ports are used by windows at the lowest level for LPCs. A call to NtConnectPort will block until the server called NtCompleteConnectPort (there is no timeout handling for calls to NtConnectPort). So your problem is that winspool.drv tries to establish an LPC connection to another process on the same machine (my guess would be spoolsv.exe, the printer spooler service, but it's impossible to tell from the information provided) and this other process has created a port (NtCreatePort) but has either not called NtListenPort on it, or when NtListenPort returns does not call NtAcceptConnectPort and NtCompleteConnectPort on it. Which prevents the call to NtConnectPort in your process from every returning. So the real problem is outside of your process, in whatever process the other side of the port belongs to.