Using Irvine Library ( :dazzled:) and without using any of the API functions, namely GetPixel.
This demo is only for 24-bit color classical BMP files (99% of them) and the bitmaps are bottom-up. The output displays "3 arrays , one for each color value of the RGB" (as per the previous exercise), but now top-down. The attachment includes a small BMP file with 4 colours.
INCLUDE Irvine32.inc
LPVOID TYPEDEF PTR VOID
MAXFILEBYTES EQU 9523200 ; Maximum 1920x1240*4 (change if not enough)
BITMAPFILEHEADER STRUCT
bfType WORD ?
bfSize DWORD ?
bfReserved1 WORD ?
bfReserved2 WORD ?
bfOffBits DWORD ?
BITMAPFILEHEADER ENDS
BITMAPINFOHEADER STRUCT
biSize DWORD ?
biWidth SDWORD ?
biHeight SDWORD ?
biPlanes WORD ?
biBitCount WORD ?
biCompression DWORD ?
biSizeImage DWORD ?
biXPelsPerMeter SDWORD ?
biYPelsPerMeter SDWORD ?
biClrUsed DWORD ?
biClrImportant DWORD ?
BITMAPINFOHEADER ENDS
CreateFileW PROTO, lpFilename:PTR, dwDesiredAccess:DWORD, dwShareMode:DWORD,
lpSecurityAttributes:PTR,
dwCreationDisposition:DWORD,
dwFlagsAndAttributes:DWORD,
hTemplateFile:HANDLE
.data
fileName dw "m","i","n","i","2","4",".","b","m","p",0,0
bmpBufferPtr LPVOID ?
heapHandle HANDLE ?
fileHandle HANDLE ?
bytesReadFromFile DWORD ?
bmpWidth DWORD ?
bmpHeight SDWORD ?
bmpBitsPerPixel WORD ?
pixelArrayStart LPVOID ?
redArray LPVOID ?
greenArray LPVOID ?
blueArray LPVOID ?
bytesperPixel DWORD ?
msgRed db "Red Color Array:",13,10,0
msgGreen db "Green Color Array:",13,10,0
msgBlue db "Blue Color Array:",13,10,0
.code
printArrays PROC
mov eax, bmpWidth
mul bmpHeight
mov ebx, eax
push ebx
call Crlf
lea edx, msgRed
call WriteString
call Crlf
mov edx, 0
mov esi, redArray
.WHILE edx<ebx
push ebx
push edx
push esi
mov al, BYTE PTR [esi]
call WriteDec
mov eax, ebx
sub eax, edx
.IF eax!=1
mov al, ','
call WriteChar
mov al, ' '
call WriteChar
.ENDIF
pop esi
pop edx
pop ebx
inc edx
inc esi
.ENDW
call Crlf
call Crlf
lea edx, msgGreen
call WriteString
call Crlf
pop ebx
push ebx
mov edx, 0
mov esi, greenArray
.WHILE edx<ebx
push ebx
push edx
push esi
mov al, BYTE PTR [esi]
call WriteDec
mov eax, ebx
sub eax, edx
.IF eax!=1
mov al, ','
call WriteChar
mov al, ' '
call WriteChar
.ENDIF
pop esi
pop edx
pop ebx
inc edx
inc esi
.ENDW
call Crlf
call Crlf
lea edx, msgBlue
call WriteString
call Crlf
pop ebx
mov edx, 0
mov esi, blueArray
.WHILE edx<ebx
push ebx
push edx
push esi
mov al, BYTE PTR [esi]
call WriteDec
mov eax, ebx
sub eax, edx
.IF eax!=1
mov al, ','
call WriteChar
mov al, ' '
call WriteChar
.ENDIF
pop esi
pop edx
pop ebx
inc edx
inc esi
.ENDW
ret
printArrays ENDP
loadBMPFromDisk PROC fName : PTR
INVOKE HeapAlloc, heapHandle, 0, MAXFILEBYTES
.IF eax==0
ret
.ENDIF
mov bmpBufferPtr, eax
INVOKE CreateFileW, fName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
.IF eax==INVALID_HANDLE_VALUE
mov eax, 0
ret
.ENDIF
mov fileHandle, eax
mov edx, bmpBufferPtr
mov ecx, MAXFILEBYTES
call ReadFromFile
.IF eax==0
ret
.ENDIF
INVOKE CloseHandle, fileHandle
ret
loadBMPFromDisk ENDP
main PROC
INVOKE GetProcessHeap
.IF eax==0
jmp @exit1
.ENDIF
mov heapHandle, eax
INVOKE loadBMPFromDisk, ADDR fileName
.IF EAX==0
jmp @exit1
.ENDIF
; Allocate space fo Color Arrays
INVOKE HeapAlloc, heapHandle, 0, MAXFILEBYTES / 3 +1
.IF eax==0
jmp @exit2
.ENDIF
mov redArray, eax
INVOKE HeapAlloc, heapHandle, 0, MAXFILEBYTES / 3+1
.IF eax==0
jmp @exit3
.ENDIF
mov greenArray, eax
INVOKE HeapAlloc, heapHandle, 0, MAXFILEBYTES / 3+1
.IF eax==0
jmp @exit4
.ENDIF
mov blueArray, eax
mov esi, bmpBufferPtr
.IF WORD PTR [esi]!="MB"
jmp @exit5
.ENDIF
mov eax, (BITMAPFILEHEADER PTR [esi]).bfOffBits
add eax, esi
mov pixelArrayStart, eax
add esi, SIZEOF BITMAPFILEHEADER
mov eax, (BITMAPINFOHEADER PTR [esi]).biWidth
mov bmpWidth, eax
mov eax, (BITMAPINFOHEADER PTR [esi]).biHeight
mov bmpHeight, eax
mov ax, (BITMAPINFOHEADER PTR [esi]).biBitCount
mov bmpBitsPerPixel, ax
cmp bmpHeight,0
jbe @endIf2 ; we will only deal with bottom-up (the normal BMP)
; go to "top"
mov eax, bmpWidth
mov ecx, bmpHeight
dec ecx ; position at the start of last scan line
mul ecx
cmp bmpBitsPerPixel, 24
jz @F ; we will deal only with 24 bit-bitmap
jmp @exit5
@@:
lea eax, [eax+2*eax]
mov ecx, 3
mov DWORD PTR bytesperPixel, ecx
mov esi, pixelArrayStart
add esi, eax
mov ebx, bmpHeight
dec ebx
@startWhile:
cmp ebx, 0
jl @endWhile
push esi
mov ecx, bmpHeight
dec ecx
sub ecx, ebx
mov eax, bmpWidth
mul ecx
mov edx, eax
mov ecx,0
.WHILE ecx<bmpWidth
NOP ; Masm bug fix
mov edi, blueArray
add edi,edx
add edi,ecx
mov al, BYTE PTR [esi]
mov BYTE PTR [edi], al
inc esi
mov edi, greenArray
add edi,edx
add edi,ecx
mov al, BYTE PTR [esi]
mov BYTE PTR [edi], al
inc esi
mov edi, redArray
add edi,edx
add edi,ecx
mov al, BYTE PTR [esi]
mov BYTE PTR [edi], al
inc esi
inc ecx
.ENDW
pop esi
mov eax, bmpWidth
mul bytesperPixel
sub esi, eax
dec ebx
jmp @startWhile
@endWhile:
@endIf2:
call printArrays
@exit5:
INVOKE HeapFree, heapHandle, 0, blueArray
@exit4:
INVOKE HeapFree, heapHandle, 0, greenArray
@exit3:
INVOKE HeapFree, heapHandle, 0, redArray
@exit2:
INVOKE HeapFree, heapHandle, 0, bmpBufferPtr
@exit1:
ret
main ENDP
END main