title: write a processed bitmap image to a file
body: <p>I'm working on a project that reads the contents of a BMP file and performs a smooth digital filter on the image. My code below almost does the job. I just don't know where I should store the processed pixels and how I can write the processed image to a file. My code below is commented out so Any help would be highly appreciated.</p>
  
  <pre><code>        .586
          .model      flat, stdcall
          option      casemap :none
          include     ..\masm32\include\windows.inc
          include     ..\masm32\include\user32.inc
          include     ..\masm32\include\kernel32.inc
          include     ..\masm32\macros\macros.asm
          include     ..\masm32\include\masm32.inc
  
          includelib  ..\masm32\lib\user32.lib
          includelib  ..\masm32\lib\kernel32.lib
          includelib  ..\masm32\lib\masm32.lib
  
          .data
  FileName    db  "bitmap2.bmp", 0
  filename    db  "bitmap_fil.bmp",0
  errMsg      BYTE    "Cannot create file",0dh,0ah,0
  
  hFile       HANDLE  ?
  hwFile      HANDLE  ?
  
  hMemory     HANDLE  ?       ;incoming data
  pMemory     DWORD   ?
  
  hMemory_o   HANDLE  ?       ;outgoing data
  pMemory_o   DWORD   ?
  
  ReadSize    DWORD   ?
  
  bytesWritten    DWORD   ?
  firstLine   DWORD   ?
  FileSize    DWORD   ?
  BDoff       DWORD   ?
  BHSize      DWORD   ?
  szTemp      byte    16 dup (0)  ;buffer for messages
  szPrime     byte    "%08i", 0   ;message format string
  szPrimeH    byte    "%08lx",0   ;message hexa format string
  signature   DD  0
  MEMORYSIZE      equ 65535   ;This is how much memory allocated
                          ; to store the file.
  im_offset   dd  ?
  im_width    dd  ?
  im_height   dd  ?
  bits_pix    dd  ?
  
  
  
  
  
      .code
  ;................................
  show    MACRO   caption, value      
      print   SADD(caption)
      mov eax, value
      invoke  wsprintf, offset szTemp, offset szPrime, eax    ;converts eax into string
      print   offset szTemp                   ;print string
      print   SADD(13,10) 
      ENDM
  ;..................................
  
  start:  
  
      invoke      CreateFile, addr FileName,GENERIC_READ,FILE_SHARE_READ,NULL, OPEN_EXISTING,     FILE_ATTRIBUTE_NORMAL, NULL
      mov      hFile, eax
  
  ;Allocate and lock the memory for incoming file.
      invoke      GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, MEMORYSIZE
      mov         hMemory, eax
      invoke      GlobalLock, hMemory
      mov         pMemory, eax
  
  ;Allocate and lock the memory for outgoing file.
      invoke      GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, MEMORYSIZE
      mov         hMemory_o, eax
      invoke      GlobalLock, hMemory_o
      mov         pMemory_o, eax
  
  
  ;Read file and save image parameters
      invoke      ReadFile, hFile, pMemory, MEMORYSIZE-1, addr ReadSize, NULL
      mov     esi, pMemory
  
      add     esi, 02     ;get filesize
      mov     edi, [esi]
      mov     FileSize,edi
      invoke      wsprintf, offset szTemp, offset szPrime, edi
      print       offset szTemp
      print       SADD(10,13)
  
      add         esi, 8      ; jump 8 bytes to get image offset
      mov     edi, [esi]  ; get image offset
      mov         im_offset,edi
      invoke      wsprintf, offset szTemp, offset szPrimeH, edi
      print       offset szTemp
      print       SADD(10,13)
  
      add     esi,8       ;jump 8 bytes to get image width
      mov     edi, [esi]  ; get image width       
      mov     im_width, edi   
      invoke      wsprintf, offset szTemp, offset szPrime, edi
      print       offset szTemp
      print       SADD(10,13)
  
      add     esi,4       ;jump 4 bytes to get image height
      mov     edi, [esi]  ; get image height
      mov     im_height, edi  
      invoke      wsprintf, offset szTemp, offset szPrime, edi
      print       offset szTemp
      print       SADD(10,13)
  
      add     esi,4       ;jump 4 bytes to get color plane
      mov     ebx, [esi]  
      shr     ebx,16      ; get color plane and bit-pix
      mov     bits_pix,ebx ;
      print       SADD("bit-per-pix ")
      invoke      wsprintf, offset szTemp, offset szPrime, ebx
      print       offset szTemp
      print       SADD(10,13)
  
      mov     ebp, pMemory    ; get ready to start processing the image
      add     ebp, im_offset  ; esi now points to the first pix
  
  ;filtering process
  ;leave first row and first column and last row and last column untouched.
  
      mov     esi,1       ; esi is the row counter
      mov     edi,1       ; edi is the column counter
  
  
  proc_pix:
      ;show       "current column is: ",edi
      ;show       "current row is: ",esi
      xor     ebx,ebx     ; ebx = 0 ebx will accumulate intermediate values for averaging
      mov     eax, im_width   ; eax is the pointer to the pixel
      mul     esi
      add     eax,edi     
      add     ebx, [ebp+eax]  ;get the pixel(I,J) 
  
      mov     eax, im_width
      add     esi,1       ;next row (I+1)
      mul     esi
      add     eax,edi     
      add     ebx, [ebp+eax]  ;get the pixel(I+1,J) 
  
  
      mov     eax, im_width
      sub     esi,2       ; prev row (I-1)
      mul     esi
      add     eax,edi     
      add     ebx, [ebp+eax]  ;get the pixel(I-1,J) 
  
      add     esi,1       ;back to the current row
  
      add     edi,1       ;get next column (J+1)
      mov     eax, im_width
      mul     esi
      add     eax,edi     
      add     ebx, [ebp+eax]  ;get the pixel(I,J+1) 
  
  
      sub     edi,2       ; get prev column (J-1)
      mov     eax, im_width
      mul     esi
      add     eax,edi     
      add     ebx, [ebp+eax]  ;get the pixel(I,J-1) 
  
      add     edi,1       ;back current column
      xor     edx, edx    ;clear upper part dividend
      mov     eax, ebx    ; move data to eax to divide
      mov     ecx, 5  
      div     ecx     ;do the average (div 5)&gt;&gt;&gt; result in eax
  
  ; where should I store the processed pixels?
  
      inc     edi     ; do the next column
      cmp     edi, im_width   
      jl      proc_pix
  
      inc             esi     ; do the next row
      mov     edi,1       ; skip the first column 
      cmp     esi, im_height  
      jl      proc_pix
  
  ;....................................................................................
  
  
  new_file: 
      invoke      CreateFile,ADDR filename, GENERIC_WRITE, NULL, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
      mov         hwFile,eax      ; save file handle
  
  ; handling of error if invalid file handle
      cmp         eax,INVALID_HANDLE_VALUE
      jne     writef
      invoke      StdOut, addr errMsg ; Display error message
      jmp         QuitNow
  
  writef: invoke      WriteFile, hwFile, pMemory_o, FileSize, ADDR bytesWritten, 0        
  
  
  QuitNow:
      invoke      GlobalUnlock, pMemory
      invoke      GlobalUnlock, pMemory_o
      invoke      GlobalFree, hMemory
      invoke      CloseHandle, hFile
      invoke      CloseHandle, hwFile
      invoke      ExitProcess, NULL
      end         start
  
  ;finish
  </code></pre>