kolibrios/programs/media/zsea/plugins/bmp/cnv_bmp.asm

660 lines
14 KiB
NASM
Raw Normal View History

;*****************************************************************************
; BMP to RAW convert plugin - for zSea image viewer
; Copyright (c) 2008-2011, Marat Zakiyanov aka Mario79, aka Mario
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Marat Zakiyanov ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
format MS COFF
public EXPORTS
section '.flat' code readable align 16
;include 'macros.inc'
include '../../../../macros.inc'
;---------------------------------------------------------------------
START:
pushad
mov eax,dword [esp+36]
call .check_header
je @f
.no_bmp_file:
xor eax,eax
mov [raw_area],eax
inc eax ; data corrupt eax = 1
jmp .ret
.check_header:
mov [pointer],eax
mov eax,[eax]
mov [image_file],eax
cmp [eax],word 'BM'
ret
;---------------------------------------------------------------------
@@:
mov [MinusHeight],byte 0
mov edx,[eax+22]
test edx,0x80000000
jz @f
neg edx
mov [eax+22],edx
mov [MinusHeight],byte 1
@@:
xor edx,edx
mov dx,[eax+28] ; color resolution 1,4,8,16,24,32 bits
; mov [ebx+16],edx ; store resolution BMP
mov [resolution],edx
mov ecx,[eax+30]
mov [compression],ecx
;---------------------------------------------------------------------
mov ecx,[eax+18] ; width BMP
imul ecx,edx ;[resolution]
mov edi,ecx
shr ecx,3
test edi,7
jz @f
inc ecx
@@:
imul ecx,[eax+22] ; size of pixels data area
;---------------------------------------------------------------------
cmp edx,16
jae .get_memory ; no palette
mov eax,4
xchg cl,dl
shl eax,cl
xchg cl,dl
add ecx,eax ; palette size
;---------------------------------------------------------------------
.get_memory:
add ecx,44 ; header
mcall 68,12
cmp eax,0
jne @f
xor eax,eax
mov [raw_area],eax
mov eax,2 ; not enough memory
jmp .ret
@@:
mov [raw_area],eax
;---------------------------------------------------------------------
mov edi,eax
xor eax,eax
shr ecx,2
cld
rep stosd ; clear memory
;---------------------------------------------------------------------
; Create RAW header
;---------------------------------------------------------------------
mov eax,[raw_area]
mov [eax],dword 'RAW '
mov ebx,[image_file]
;---------------------------------------------------------------------
mov ecx,[ebx+18] ; width BMP
mov [eax+4],ecx ; width RAW
;---------------------------------------------------------------------
mov ecx,[ebx+22] ; high BMP
mov [eax+8],ecx ; high RAW
;---------------------------------------------------------------------
mov ecx,[resolution] ; color resolution BMP
mov [eax+12],ecx ; color resolution RAW
;---------------------------------------------------------------------
mov ecx,[resolution]
cmp ecx,16
jb .1
push eax
mov eax,ecx
mov ecx,3
xor edx,edx
div ecx
cmp eax,8
jbe @f
mov eax,8
@@:
mov ecx,eax
pop eax
.1:
mov [eax+16],cx ; channel color resolution RAW
;---------------------------------------------------------------------
mov ecx,[resolution]
cmp ecx,16
jae @f
mov [eax+18],word 1 ; channels amount RAW
jmp .2
@@:
mov [eax+18],word 3 ; channels amount RAW
.2:
;---------------------------------------------------------------------
xor edx,edx
cmp ecx,16
jae @f
add edx,44
@@:
mov [eax+20],edx ; palette pointer (offset from file start)
;---------------------------------------------------------------------
mov ecx,[resolution]
cmp ecx,16
jae @f
mov ecx,[resolution]
push eax
mov eax,1
shl eax,cl
mov ecx,eax
pop eax
shl ecx,2
jmp .3
@@:
xor ecx,ecx
.3:
mov [eax+24],ecx ; palette area size
;---------------------------------------------------------------------
add ecx,dword 44
mov [eax+28],ecx ; pixels pointer (offset from file start)
;---------------------------------------------------------------------
mov ecx,[ebx+18] ; width BMP
imul ecx,[resolution]
mov edi,ecx
shr ecx,3
test edi,7
jz @f
inc ecx
@@:
imul ecx,[ebx+22] ; high BMP
mov [eax+32],ecx ; pixels area size
;---------------------------------------------------------------------
xor ecx,ecx ; Stub!!!
mov [eax+36],ecx ; Transparency pointer (offset from file start)
mov [eax+40],ecx ; Transparency area size
;---------------------------------------------------------------------
; Finish create RAW header
;---------------------------------------------------------------------
; mov ebx,[pointer]
; mov [ebx+4],eax ; store [soi] pointer of image area
; mov ecx,eax
.convert:
cmp [resolution],16
jae .no_palette
; mov [ebx+24],eax
; mov edi,eax
mov edi,[raw_area]
mov edi,[edi+20] ; palette pointer (offset from file start)
add edi,[raw_area]
mov esi,[image_file]
add esi,54
mov ecx,[resolution]
mov eax,1
shl eax,cl
mov ecx,eax
rep movsd
; mov [ebx+4],edi ; store [soi] pointer of image area
.no_palette:
mov ecx,[raw_area]
mov ecx,[ecx+28] ; pixels pointer (offset from file start)
add ecx,[raw_area]
;---------------------------------------------------------------------
mov eax,[image_file]
mov ebp,[eax+18] ; width BMP
; mov [ebx+8],ebp ; store width
imul ebp,[resolution]
mov edi,ebp
shr ebp,3 ; ebp = size of output scanline
test edi,7
jz @f
inc ebp
@@:
mov eax,[eax+22] ; high BMP
; mov [ebx+12],eax ; store high
dec eax
mul ebp
add eax,ecx
mov edi,ecx
mov bl,[MinusHeight]
test bl,bl
jnz @f
mov edi,eax ; edi points to last scanline
@@:
mov esi,[image_file]
add esi,[esi+10] ; start of pixels data
mov ebx,[image_file]
mov edx,[ebx+22] ; high BMP
add ebx,54
lea eax,[ebp*2]
mov [delta],eax
test edx,edx
jz .ret
jns @f
neg edx
and [delta], 0
mov edi,ecx
@@:
;---------------------------------------------------------------------
cmp [compression],3
je .BI_BITFIELDS ; @f
cmp [compression],2
je RLE4
cmp [compression],1
je RLE8
cmp [compression],0
je @f
jmp .no_bmp_file
;---------------------------------------------------------------------
@@:
cmp [resolution],16
jne .continue
mov ebx,[raw_area]
mov [ebx+12],dword 15
jmp .continue
;---------------------------------------------------------------------
.BI_BITFIELDS:
cmp [resolution],32
je .32
cmp [resolution],16
jne .continue
mov ebx,[raw_area]
mov eax,[image_file]
cmp [eax+54],dword 0x7C00
jne @f
mov [ebx+12],dword 15
jmp .continue
;---------------------------------------------------------------------
@@:
cmp [eax+54],dword 0xF800
jne @f
mov [ebx+12],dword 16
jmp .continue
;---------------------------------------------------------------------
@@:
cmp [eax+54],dword 0xF00
jne .no_bmp_file ; @f
mov [ebx+12],dword 15
@@:
mov ebx,ebp
neg ebx
and ebx,3
mov [aligner],ebx
shr ebp,1
mov cl,[MinusHeight]
test cl,cl
jnz .start_16_1
align 4
.start_16:
mov ecx,ebp
call .process_16b_x4r4g4b4
sub edi,[delta]
add esi,[aligner]
dec edx
jnz .start_16
jmp .ret_ok
;---------------------------------------------------------------------
.process_16b_x4r4g4b4:
cld
@@:
lodsw
xor ebx,ebx
mov bx,ax
xor eax,eax
ror ebx,8
and bl,0xf
mov al,bl
shl eax,6
rol ebx,4
and bx,0xf
shl bl,1
add ax,bx
shl eax,5
rol ebx,4
and bx,0xf
shl bl,1
add ax,bx
stosw
dec ecx
jnz @r
ret
;---------------------------------------------------------------------
.start_16_1: ;negative value of Height
mov ecx,ebp
call .process_16b_x4r4g4b4
add esi,[aligner]
dec edx
jnz .start_16_1
jmp .ret_ok
;---------------------------------------------------------------------
.32:
mov eax,[image_file]
cmp [eax+54],dword 0xFF000000
jne .no_bmp_file
shr ebp,2
mov al,[MinusHeight]
test al,al
jnz .start_32_1
align 4
.start_32:
mov ecx,ebp
@@:
cld
lodsd
shr eax,8
stosd
dec ecx
jnz @r
sub edi,[delta]
dec edx
jnz .start_32
jmp .ret_ok
;---------------------------------------------------------------------
.start_32_1: ;negative value of Height
mov ecx,ebp
imul ecx,edx
@@:
cld
lodsd
shr eax,8
stosd
dec ecx
jnz @r
jmp .ret_ok
;---------------------------------------------------------------------
.continue:
mov eax,ebp
neg eax
and eax,3
mov cl,[MinusHeight]
test cl,cl
jz .start_24
cld
align 4
@@: ;negative value of Height
mov ecx,ebp
rep movsb
add esi,eax
dec edx
jnz @r
jmp .ret_ok
;---------------------------------------------------------------------
align 4
.start_24:
@@:
mov ecx,ebp
rep movsb
sub edi,[delta]
add esi,eax
dec edx
jnz .start_24 ; @r
.ret_ok:
mov eax,0 ; convert OK
.ret:
mov ebx,[pointer]
mov [ebx+8],eax ; store return code
mov eax,[raw_area]
mov [ebx+4],eax ; store RAW pointer
popad
ret 4
;---------------------------------------------------------------------
RLE4:
cmp [resolution],4
jne START.no_bmp_file
xor ebx,ebx
xor edx,edx
align 4
.start:
cld
lodsb
cmp al,0
jnz .Encoded_Mode
cld
lodsb
cmp al,0
jz .end_line
cmp al,1
jz START.ret_ok ; .end_bitmap
cmp al,2
jz .Delta
.Absolute_Mode:
xor ecx,ecx
mov cl,al
add ebx,ecx
cmp dl,0
je @f
mov dh,[esi]
shr dh,4
mov dl,[edi-1]
and dl,11110000b
add dl,dh
mov [edi-1],dl
dec ecx
xor edx,edx
mov dh,1
@@:
test cl,1b
jz @f
inc ecx
inc edx
@@:
shr ecx,1
cmp dh,1
je .1
mov eax,ecx
cld
rep movsb
test eax,1b
jz @f
inc esi
@@:
jmp .start
;---------------------------------------------------------------------
.1:
mov dh,cl
@@:
cld
lodsb
mov ah,[esi]
shl al,4
shr ah,4
add al,ah
cld
stosb
dec ecx
jnz @r
test dh,1b
jz @f
inc esi
@@:
xor dh,dh
jmp .start
;---------------------------------------------------------------------
.Encoded_Mode:
xor ecx,ecx
mov cl,al
add ebx,ecx
cld
lodsb
cmp dl,0
je @f
rol al,4
mov dh,al
and dh,00001111b
mov dl,[edi-1]
and dl,11110000b
add dl,dh
mov [edi-1],dl
dec ecx
xor edx,edx
@@:
test cl,1b
jz @f
inc ecx
inc edx
@@:
shr ecx,1
cld
rep stosb
cmp dl,0
je @f
mov al,[edi-1]
and al,11110000b
mov [edi-1],al
@@:
jmp .start
;---------------------------------------------------------------------
.Delta:
xor eax,eax
cld
lodsb
add ebx,eax
cmp dl,0
je @f
dec eax
xor edx,edx
@@:
test al,1b
jz @f
inc eax
inc edx
@@:
shr eax,1
add edi,eax
cld
lodsb
imul eax,ebp
sub edi,eax
jmp .start
;---------------------------------------------------------------------
.end_line:
mov eax,ebp
test ebx,1b
jz @f
inc ebx
@@:
shr ebx,1
sub eax,ebx
add edi,eax
sub edi,[delta]
xor ebx,ebx
xor edx,edx
jmp .start
;---------------------------------------------------------------------
RLE8:
cmp [resolution],8
jne START.no_bmp_file
xor ebx,ebx
align 4
.start:
cld
lodsb
cmp al,0
jnz .Encoded_Mode
cld
lodsb
cmp al,0
jz .end_line
cmp al,1
jz START.ret_ok ; .end_bitmap
cmp al,2
jz .Delta
.Absolute_Mode:
xor ecx,ecx
mov cl,al
add ebx,ecx
mov eax,ecx
cld
rep movsb
test eax,1b
jz @f
inc esi
@@:
jmp .start
;---------------------------------------------------------------------
.Encoded_Mode:
xor ecx,ecx
mov cl,al
add ebx,ecx
cld
lodsb
rep stosb
jmp .start
;---------------------------------------------------------------------
.Delta:
xor eax,eax
cld
lodsb
add edi,eax
add ebx,eax
cld
lodsb
imul eax,ebp
sub edi,eax
jmp .start
;---------------------------------------------------------------------
.end_line:
mov eax,ebp
sub eax,ebx
add edi,eax
xor ebx,ebx
sub edi,[delta]
jmp .start
;---------------------------------------------------------------------
Check_Header:
pushad
mov eax,dword [esp+36]
call START.check_header
jne START.no_bmp_file
popad
ret 4
;---------------------------------------------------------------------
Associations:
dd Associations.end - Associations
db 'BMP',0
.end:
db 0
;---------------------------------------------------------------------
align 16
EXPORTS:
dd szStart, START
dd szVersion, 0x00010002
dd szCheck, Check_Header
dd szAssoc, Associations
dd 0
pointer dd 0
image_file dd 0
delta dd 0
aligner dd 0
resolution dd 0
compression dd 0
raw_area dd 0
MinusHeight db 0
szStart db 'START',0
szVersion db 'version',0
szCheck db 'Check_Header',0
szAssoc db 'Associations',0
;---------------------------------------------------------------------