kolibrios/programs/media/zsea/plugins/gif/cnv_gif.asm
Marat Zakiyanov (Mario79) d7b0867c02 zSea - advanced image viewer for KolibriOS
v.1.0 rс3 12.06.2011

git-svn-id: svn://kolibrios.org@1951 a494cfbc-eb01-0410-851d-a64ba20cac60
2011-06-11 22:16:26 +00:00

535 lines
12 KiB
NASM

;*****************************************************************************
; GIF to RAW1 convert plugin - for zSea image viewer
; Copyright (c) 2009, Evgeny Grechnikov aka Diamond
; 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 Evgeny Grechnikov ''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.
;*****************************************************************************
; Based on gif_lite.inc (c) Ivuskin Andrey aka Willow and Diamond 2004-2007
;*****************************************************************************
; Some small changes (c) 2011 Marat Zakiyanov aka Mario79, aka Mario
;*****************************************************************************
format MS COFF
public EXPORTS
section '.flat' code readable align 16
START:
pushad
mov eax,dword [esp+36]
mov esi, [eax] ; esi -> GIF data
mov ebp, [eax+12] ; ebp = file size
xor ebx, ebx ; ebx -> list of images, not allocated yet
call check_header_1
jz ReadGIF
ReadGIF.end:
; general exit from the function
xor eax, eax
cmp ebx, eax
jz .bad
cmp dword [ebx+4], eax
jnz ReadGIF.ret
mov ecx, ebx
push 68
pop eax
push 13
pop ebx
int 40h
xor ebx, ebx
.bad:
inc eax ; bad image
ReadGIF.ret:
mov ecx, [esp+28]
mov [ecx+4], ebx ; save RAW data ptr
mov [ecx+8], eax ; save result
popad
ret 4
ReadGIF.animated.ret:
mov ebx, [ReadGIF.gifList]
jmp ReadGIF.ret
_null fix 0x1000
ReadGIF:
; allocate one page for list of images
mov ecx, 0x1000
push 68
pop eax
push 12
pop ebx
int 40h
xchg eax, ebx
test ebx, ebx
jnz @f
mov al, 2 ; no memory
jmp .ret
@@:
mov dword[ebx],'RAW1'
xor eax,eax
mov [.globalColor],eax
mov [.globalColorSize],eax
mov [.curImageIndex],eax
sub ebp,0xd
jb .end
movzx eax,word[esi+6]
mov [ebx+8],eax
movzx eax,word[esi+8]
mov [ebx+12],eax
mov cl,[esi+0xa]
add esi,0xd
test cl,cl
jns .nextblock
mov [.globalColor],esi
push ebx
call .Gif_skipmap
mov [.globalColorSize],ebx
pop ebx
jb .end
.nextblock:
dec ebp
js .end
cmp byte[esi],0x21
jne .noextblock
inc esi
cmp byte[esi],0xf9 ; Graphic Control Ext
jne .no_gc
sub ebp,7
jc .end
mov ecx,[ebx+4]
shl ecx,4
add ecx,ebx
mov eax,[esi+3]
mov [ecx+16+12],ax
; test byte[esi+2],1
; setnz byte[ecx+16+14]
mov al,[esi+2]
mov [ecx+16+14], al
mov al,[esi+5]
mov [ecx+16+15],al
add esi,7
jmp .nextblock
.no_gc:
inc esi
xor eax,eax
.block_skip:
dec ebp
js .end
lodsb
add esi,eax
sub ebp,eax
jc .end2
test eax,eax
jnz .block_skip
jmp .nextblock
.noextblock:
cmp byte[esi],0x2c ; image beginning
jne .end
inc esi
sub ebp,11
jc .end2
movzx ecx,word[esi+4] ; ecx = width
jecxz .end2
mov [.width],ecx
movzx eax,word[esi+6] ; eax = height
test eax,eax
jz .end2
push eax ecx
imul ecx,eax
cmp ecx,4000000h
jb @f
pop ecx eax
.end2:
jmp .end
@@:
push ebx
push ecx
add ecx,44+256*4
push 68
pop eax
push 12
pop ebx
int 0x40
pop ecx
pop ebx
test eax,eax
jnz @f
pop ecx ecx
jmp .end2
@@:
xchg eax,edi
inc dword[ebx+4]
mov [edi+32],ecx ; size of pixels area
mov byte[edi+20],44 ; pointer to palette
mov byte[edi+24+1],4 ; size of palette=256*4
mov dword[edi+28],44+256*4 ; pointer to RAW data
pop ecx eax
mov dword[edi], 'RAW ' ; signature
mov dword[edi+4],ecx ; width
mov dword[edi+8],eax ; height
mov byte[edi+12],8 ; total pixel size
mov byte[edi+16],8 ; 8 bits per component
mov byte[edi+18],1 ; number of components
mov eax,[ebx+4]
shl eax,4
add eax,ebx
mov [eax],edi
movzx ecx,word[esi]
mov [eax+4],ecx
movzx ecx,word[esi+2]
mov [eax+8],ecx
mov eax,[edi+32]
mov [.img_end],eax
inc eax
mov [.row_end],eax
and [.pass],0
test byte[esi+8],40h
jz @f
mov ecx,[edi+4]
mov [.row_end],ecx
@@:
mov cl,[esi+8]
add esi,9
add edi,44
push edi
test cl,cl
js .uselocal
push esi
mov esi,[.globalColor]
mov ecx,[.globalColorSize]
call .swap_palette
pop esi
jmp .setPal
.uselocal:
push ebx
call .Gif_skipmap
jnc @f
pop ebx
pop edi
jmp .end
@@:
sub esi,ebx
mov ecx,ebx
pop ebx
call .swap_palette
.setPal:
movzx ecx,byte[esi]
inc ecx
mov [.codesize],ecx
dec ecx
inc esi
mov edi,.gif_workarea
xor eax,eax
lodsb ; eax - block_count
add eax,esi
mov [.block_ofs],eax
mov [.bit_count],8
mov eax,1
shl eax,cl
mov [.CC],eax
mov ecx,eax
inc eax
mov [.EOI],eax
mov eax, _null shl 16
.filltable:
stosd
inc eax
loop .filltable
pop edi
add edi,256*4
mov [.img_start],edi
add [.img_end],edi
add [.row_end],edi
mov [.ebx],ebx
.reinit:
mov edx,[.EOI]
inc edx
push [.codesize]
pop [.compsize]
call .Gif_get_sym
cmp eax,[.CC]
je .reinit
call .Gif_output
.cycle:
movzx ebx,ax
call .Gif_get_sym
cmp eax,edx
jae .notintable
cmp eax,[.CC]
je .reinit
cmp eax,[.EOI]
je .unpend
call .Gif_output
.add:
mov dword [.gif_workarea+edx*4],ebx
cmp edx,0xFFF
jae .cycle
inc edx
bsr ebx,edx
cmp ebx,[.compsize]
jne .noinc
inc [.compsize]
.noinc:
jmp .cycle
.notintable:
push eax
mov eax,ebx
call .Gif_output
push ebx
movzx eax,bx
call .Gif_output
pop ebx eax
jmp .add
.unpend:
mov ebx,[.ebx]
add ebp,esi
mov esi,[.block_ofs]
sub ebp,esi
jc .end2
xor eax,eax
@@:
dec ebp
js .end2
lodsb
test eax,eax
jz @f
sub ebp,eax
jc .end2
add esi,eax
jmp @b
@@:
test ebp,ebp
jz .end2
cmp byte[esi],0x3b
jz .end2
; next image
mov ecx,[ebx+4]
cmp cl,0xFF
jnz .noresize
mov edx,ebx
inc ecx
inc ecx
shl ecx,4
push 68
pop eax
push 20
pop ebx
int 40h
test eax,eax
jnz @f
mov ebx,edx
jmp .end2
@@:
xchg ebx,eax
.noresize:
jmp .nextblock
.Gif_skipmap:
; in: ecx - image descriptor, esi - pointer to colormap
; out: edi - pointer to area after colormap
and ecx,111b ; color map size
mov ebx,3*2
shl ebx,cl
add esi,ebx
sub ebp,ebx
ret
.Gif_get_sym:
mov ecx,[.compsize]
push ecx
xor eax,eax
.shift:
ror byte[esi],1
rcr eax,1
dec [.bit_count]
jnz .loop1
inc esi
cmp esi,[.block_ofs]
jb .noblock
push eax
xor eax,eax
dec ebp
js .dataend
lodsb
test eax,eax
jnz .nextbl
mov eax,[.EOI]
sub esi,2
add esp,8
jmp .exx
.nextbl:
add eax,esi
mov [.block_ofs],eax
pop eax
.noblock:
mov [.bit_count],8
.loop1:
loop .shift
pop ecx
rol eax,cl
.exx:
xor ecx,ecx
ret
.dataend:
pop eax eax
mov ebx, [.ebx]
jmp .end2
.Gif_output:
push esi eax edx
mov edx,.gif_workarea
.next:
push word[edx+eax*4]
mov ax,word[edx+eax*4+2]
inc ecx
cmp ax,_null
jnz .next
shl ebx,16
mov bx,[esp]
.loop2:
pop ax
stosb
cmp edi,[.row_end]
jb .norowend
mov eax,[.width]
push eax
sub edi,eax
add eax,eax
cmp [.pass],3
jz @f
add eax,eax
cmp [.pass],2
jz @f
add eax,eax
@@:
add edi,eax
pop eax
cmp edi,[.img_end]
jb .nextrow
mov edi,[.img_start]
inc [.pass]
add edi,eax
cmp [.pass],3
jz @f
add edi,eax
cmp [.pass],2
jz @f
add edi,eax
add edi,eax
@@:
.nextrow:
add eax,edi
mov [.row_end],eax
xor eax,eax
.norowend:
loop .loop2
pop edx eax esi
ret
.swap_palette:
xor eax,eax
@@:
lodsb
mov ah,al
lodsb
shl eax,8
lodsb
stosd
sub ecx,3
jnz @b
ret
;---------------------------------------------------------------------
check_header_1:
and dword [eax+8], 0
cmp dword [eax+12], 6
jb .err
push eax
mov eax, [eax]
cmp dword [eax], 'GIF8'
jnz .errpop
cmp byte [eax+5], 'a'
jnz .errpop
cmp byte [eax+4], '7'
jz @f
cmp byte [eax+4], '9'
jnz .errpop
@@:
pop eax
ret
.errpop:
pop eax
.err:
inc dword [eax+8]
ret
;---------------------------------------------------------------------
check_header:
pushad
mov eax,dword [esp+36]
call check_header_1
popad
ret 4
;---------------------------------------------------------------------
Associations:
dd Associations.end - Associations
db 'GIF',0
.end:
db 0
;---------------------------------------------------------------------
align 4
EXPORTS:
dd szStart, START
dd szVersion, 0x00010002
dd szCheck, check_header
dd szAssoc, Associations
dd 0
szStart db 'START',0
szVersion db 'version',0
szCheck db 'Check_Header',0
szAssoc db 'Associations',0
section '.data' data readable writable align 16
ReadGIF.globalColor rd 1
ReadGIF.globalColorSize rd 1
ReadGIF.cur_info rd 1 ; image table pointer
ReadGIF.codesize rd 1
ReadGIF.compsize rd 1
ReadGIF.bit_count rd 1
ReadGIF.CC rd 1
ReadGIF.EOI rd 1
ReadGIF.block_ofs rd 1
ReadGIF.row_end rd 1
ReadGIF.img_end rd 1
ReadGIF.img_start rd 1
ReadGIF.pass rd 1
ReadGIF.width rd 1
ReadGIF.ebx rd 1
ReadGIF.gifList rd 1
ReadGIF.curImageIndex rd 1
ReadGIF.gif_workarea rb 16*1024