0,0 → 1,534 |
;***************************************************************************** |
; 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 |