libimg: bmp 24/32bpp encoding

git-svn-id: svn://kolibrios.org@2692 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Ivan Baravy 2012-05-27 00:00:29 +00:00
parent ef860d6920
commit 735d94c630
2 changed files with 226 additions and 6 deletions

View File

@ -98,7 +98,9 @@ img.decode.bmp.length_rest equ length_rest
jz .normal jz .normal
cmp eax, 56 ; 0x38 cmp eax, 56 ; 0x38
je .normal je .normal
cmp eax, 108 ; 0x6C cmp eax, 0x6C
je .normal
cmp eax, 0x7C
jnz .error jnz .error
; convert images with <= 8 bpp to 8bpp, other - to 32 bpp ; convert images with <= 8 bpp to 8bpp, other - to 32 bpp
.normal: .normal:
@ -259,16 +261,234 @@ img.decode.bmp.length_rest equ length_rest
endp endp
;;================================================================================================;; ;;================================================================================================;;
proc img.encode.bmp _img, _p_length, _options ;///////////////////////////////////////////////////;; proc img.encode.bmp _img, _common, _specific ;////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;; ;;------------------------------------------------------------------------------------------------;;
;? Encode image into raw data in BMP format ;; ;? Encode image into raw data in BMP format ;;
;;------------------------------------------------------------------------------------------------;; ;;------------------------------------------------------------------------------------------------;;
;> _img = pointer to image ;; ;> [_img] = pointer to image ;;
;> [_common] = format independent options ;;
;> [_specific] = 0 / pointer to the structure of format specific options ;;
;;------------------------------------------------------------------------------------------------;; ;;------------------------------------------------------------------------------------------------;;
;< eax = 0 (error) or pointer to encoded data ;; ;< eax = 0 / pointer to encoded data ;;
;< _p_length = encoded data length ;; ;< ecx = error code / the size of encoded data ;;
;;================================================================================================;; ;;================================================================================================;;
locals
bytes_per_scanline rd 1
encoded_file rd 1
encoded_file_size rd 1
encoded_data_size rd 1
endl
mov ebx, [_img]
mov eax, [ebx + Image.Type]
cmp eax, Image.bpp24
je .bpp24
cmp eax, Image.bpp32
je .bpp32
mov ecx, LIBIMG_ERROR_BIT_DEPTH
jmp .error
.bpp24:
mov eax, [ebx + Image.Width]
call img._.get_scanline_len
test eax, 0x03
jz @f
and al, 0xfc
add eax, 4
@@:
mov [bytes_per_scanline], eax
imul eax, [ebx + Image.Height]
mov [encoded_data_size], eax
add eax, 108 + 14
mov [encoded_file_size], eax
stdcall [mem.alloc], eax
test eax, eax
jz .error
mov [encoded_file], eax
mov edi, eax
mov word[edi], 'BM'
add edi, 2
mov eax, [encoded_file_size]
stosd
xor eax, eax xor eax, eax
stosd
mov eax, 108 + 14
stosd
mov eax, 108
stosd
mov eax, [ebx + Image.Width]
stosd
mov eax, [ebx + Image.Height]
stosd
mov ax, 1 ; Planes
stosw
mov ax, 24 ; BitCount
stosw
mov eax, bmp.BI_RGB
stosd
mov eax, [encoded_data_size]
stosd
mov eax, 0x00000B13
stosd
stosd
xor eax, eax
stosd
stosd
mov eax, 'BGRs'
stosd
xor eax, eax
stosd
stosd
stosd
stosd
stosd
stosd
stosd
stosd
stosd
stosd
stosd
stosd
mov eax, 2
stosd
xor eax, eax
stosd
stosd
stosd
mov esi, [ebx + Image.Data]
mov ecx, [ebx + Image.Width]
lea ecx, [ecx*3]
mov eax, [ebx + Image.Height]
mov edx, [bytes_per_scanline]
sub edx, ecx
mov dh, cl
and dh, 3
shr ecx, 2
push ecx
add edi, [encoded_data_size]
sub edi, [bytes_per_scanline]
@@:
pop ecx
push ecx
rep movsd
mov cl, dh
rep movsb
mov cl, dl
add edi, ecx
sub edi, [bytes_per_scanline]
sub edi, [bytes_per_scanline]
dec eax
jnz @b
pop ecx
mov eax, [encoded_file]
mov ecx, [encoded_file_size]
jmp .quit
.bpp32:
mov eax, [ebx + Image.Width]
call img._.get_scanline_len
mov [bytes_per_scanline], eax
imul eax, [ebx + Image.Height]
mov [encoded_data_size], eax
add eax, 0x7C + 14
mov [encoded_file_size], eax
stdcall [mem.alloc], eax
test eax, eax
jz .error
mov [encoded_file], eax
mov edi, eax
mov word[edi], 'BM'
add edi, 2
mov eax, [encoded_file_size]
stosd
xor eax, eax
stosd
mov eax, 0x7C + 14
stosd
mov eax, 0x7C
stosd
mov eax, [ebx + Image.Width]
stosd
mov eax, [ebx + Image.Height]
stosd
mov ax, 1 ; Planes
stosw
mov ax, 32 ; BitCount
stosw
mov eax, 3 ; WTF? bmp.BI_RGB
stosd
mov eax, [encoded_data_size]
stosd
mov eax, 0x00000B13
stosd
stosd
xor eax, eax
stosd
stosd
mov eax, 0xFF000000
stosd
shr eax, 8
stosd
shr eax, 8
stosd
; shr eax, 8
xor eax, eax
stosd
mov eax, 'BGRs'
stosd
xor eax, eax
stosd
stosd
stosd
stosd
stosd
stosd
stosd
stosd
stosd
stosd
stosd
stosd
mov eax, 2
stosd
xor eax, eax
stosd
stosd
stosd
mov esi, [ebx + Image.Data]
mov ecx, [ebx + Image.Width]
mov eax, [ebx + Image.Height]
add edi, [encoded_data_size]
sub edi, [bytes_per_scanline]
push ecx
.next_line:
pop ecx
push ecx
push eax
@@:
dec ecx
js @f
lodsd
rol eax, 8
stosd
jmp @b
@@:
sub edi, [bytes_per_scanline]
sub edi, [bytes_per_scanline]
pop eax
dec eax
jnz .next_line
pop ecx
mov eax, [encoded_file]
mov ecx, [encoded_file_size]
jmp .quit
.error:
xor eax, eax
.quit:
ret ret
endp endp

View File

@ -1879,7 +1879,7 @@ endp
align 4 align 4
img.formats_table: img.formats_table:
.bmp dd LIBIMG_FORMAT_ID_BMP, img.is.bmp, img.decode.bmp, img.encode.bmp, 0 .bmp dd LIBIMG_FORMAT_ID_BMP, img.is.bmp, img.decode.bmp, img.encode.bmp, 1 + (1 SHL Image.bpp24) + (1 SHL Image.bpp32)
.ico dd LIBIMG_FORMAT_ID_ICO, img.is.ico, img.decode.ico_cur, img.encode.ico, 0 .ico dd LIBIMG_FORMAT_ID_ICO, img.is.ico, img.decode.ico_cur, img.encode.ico, 0
.cur dd LIBIMG_FORMAT_ID_CUR, img.is.cur, img.decode.ico_cur, img.encode.cur, 0 .cur dd LIBIMG_FORMAT_ID_CUR, img.is.cur, img.decode.ico_cur, img.encode.cur, 0
.gif dd LIBIMG_FORMAT_ID_GIF, img.is.gif, img.decode.gif, img.encode.gif, 0 .gif dd LIBIMG_FORMAT_ID_GIF, img.is.gif, img.decode.gif, img.encode.gif, 0