Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3054 → Rev 3055

/programs/develop/libraries/libs-dev/libimg/tga/tga.asm
1,5 → 1,5
;;================================================================================================;;
;;//// tga.asm //// (c) Nable, 2007-2008 /////////////////////////////////////////////////////////;;
;;//// tga.asm //// (c) Nable, 2007-2008, (c) dunkaist, 2012 /////////////////////////////////////;;
;;================================================================================================;;
;; ;;
;; This file is part of Common development libraries (Libs-Dev). ;;
19,6 → 19,8
;; ;;
;; References: ;;
;; 1. Hiview 1.2 by Mohammad A. REZAEI ;;
;; 2. Truevision TGA FILE FORMAT SPECIFICATION Version 2.0 ;;
;; Technical Manual Version 2.2 January, 1991 ;;
;; ;;
;;================================================================================================;;
 
37,34 → 39,37
push ebx
cmp [_length], 18
jbe .nope
mov eax, [_data]
mov ebx,[eax+1] ;bl=cmatype,bh=subtype
cmp bl,1 ;cmatype is in [0..1]
mov ebx, [_data]
mov eax, dword[ebx + tga_header.colormap_type]
cmp al, 1
ja .nope
cmp bh,11 ;subtype is in [1..3] (non-rle) or in [9..11] (rle)
cmp ah, 11
ja .nope
cmp bh,9
cmp ah, 9
jae .cont1
cmp bh,3
cmp ah, 3
ja .nope
.cont1: ;continue testing
mov ebx,[eax+16] ;bl=bpp, bh=flags //image descriptor
test ebx,111b ;bpp must be 8, 15, 16, 24 or 32
.cont1:
mov eax, dword[ebx + tga_header.image_spec.depth]
test eax, 111b ; bpp must be 8, 15, 16, 24 or 32
jnz .maybe15
shr bl,3
cmp bl,4
shr al, 3
cmp al, 4
ja .nope
jmp .cont2
.maybe15:
cmp bl,15
cmp al, 15
jne .nope
.cont2: ;continue testing
test bh,tga.flags.interlace_type ;deinterlacing is not supported yet
jnz .nope
cmp byte[eax+7],24 ;test palette bpp - only 24 and 32 are supported
movzx eax, byte[ebx + tga_header.colormap_spec.entry_size] ; palette bpp
cmp eax, 0
je .yep
cmp byte[eax+7],32 ;test palette bpp - only 24 and 32 are supported
cmp eax, 16
je .yep
cmp eax, 24
je .yep
cmp eax, 32
je .yep
.nope:
xor eax, eax
pop ebx
88,51 → 93,74
;< eax = 0 (error) or pointer to image ;;
;;================================================================================================;;
locals
IMGwidth dd ?
IMGheight dd ?
IMGbpp dd ?
DupPixelCount dd ?
TgaBlockCount dd ?
width dd ?
height dd ?
bytes_per_pixel dd ?
retvalue dd ?
endl
pushad
cld ;paranoia
and [DupPixelCount],0 ;prepare variables
and [TgaBlockCount],0 ;prepare variables
mov eax,[_data]
movzx esi,byte[eax]
lea esi,[esi+eax+18] ;skip comment and header
mov ebx,[eax+12]
movzx ecx,bx ;ecx=width
shr ebx,16 ;ebx=height
mov [IMGwidth],ecx
mov [IMGheight],ebx
movzx edx,byte[eax+16]
cmp edx,16
jnz @f
dec edx ;16bpp tga images are really 15bpp ARGB
push ebx esi edi
mov ebx, [_data]
movzx esi, byte[ebx]
lea esi, [esi + ebx + sizeof.tga_header] ; skip comment and header
mov edx, dword[ebx + tga_header.image_spec.width]
movzx ecx, dx ; ecx = width
shr edx, 16 ; edx = height
mov [width], ecx
mov [height], edx
movzx eax, byte[ebx + tga_header.image_spec.depth]
add eax, 7
shr eax, 3
mov [bytes_per_pixel], eax
movzx eax, byte[ebx + tga_header.image_spec.depth]
 
cmp eax, 8
jne @f
mov eax, Image.bpp8i
jmp .type_defined
@@:
sub edx, 16 - Image.bpp16 ; 15 -> Image.bpp15, 16 -> Image.bpp16
mov [IMGbpp],edx
stdcall img.create,ecx,ebx,edx
mov [esp+28],eax ;save return value
cmp eax, 15
jne @f
mov eax, Image.bpp15
jmp .type_defined
@@:
cmp eax, 16
jne @f
mov eax, Image.bpp15 ; 16bpp tga images are really 15bpp ARGB
jmp .type_defined
@@:
cmp eax, 24
jne @f
mov eax, Image.bpp24
jmp .type_defined
@@:
cmp eax, 32
jne @f
mov eax, Image.bpp32
jmp .type_defined
@@:
.type_defined:
stdcall img.create, ecx, edx, eax
mov [retvalue], eax
test eax,eax ;failed to allocate?
jz .locret ;then exit
cmp edx,8
jz .done ; then exit
mov ebx, eax
cmp dword[ebx + Image.Type], Image.bpp8i
jne .palette_parsed
mov edi,[eax+Image.Palette]
mov edi, [ebx + Image.Palette]
mov ecx,[_data]
cmp byte[ecx+2],3 ;we also have grayscale subtype
cmp byte[ecx + tga_header.image_type], 3 ; we also have grayscale subtype
jz .write_grayscale_palette ;that don't hold palette in file
cmp byte[ecx+2],11
cmp byte[ecx + tga_header.image_type], 11
jz .write_grayscale_palette
mov dh,[ecx+7] ;size of colormap entries in bits
movzx ecx,word[ecx+5] ;number of colormap entries
cmp dh,24
jz .skip_24bpp_palette ;test if colormap entries are 24bpp
movzx eax, byte[ecx + tga_header.colormap_spec.entry_size] ; size of colormap entries in bits
movzx ecx, word[ecx + tga_header.colormap_spec.colormap_length] ; number of colormap entries
cmp eax, 24
je .24bpp_palette
cmp eax, 16
je .16bpp_palette
rep movsd ;else they are 32 bpp
jmp .palette_parsed
.write_grayscale_palette:
push eax
mov ecx,0x100
xor eax,eax
@@:
139,80 → 167,93
stosd
add eax,0x010101
loop @b
pop eax
jmp .palette_parsed
.skip_24bpp_palette:
push eax
.16bpp_palette: ; FIXME: code copypasted from img.do_rgb, should use img.convert
push ebx edx ebp
@@:
movzx eax, word[esi]
mov ebx, eax
add esi, 2
and eax, (0x1F) or (0x1F shl 10)
and ebx, 0x1F shl 5
lea edx, [eax + eax]
shr al, 2
mov ebp, ebx
shr ebx, 2
shr ah, 4
shl dl, 2
shr ebp, 7
add eax, edx
add ebx, ebp
mov [edi], al
mov [edi + 1], bl
mov [edi + 2], ah
add edi, 4
loop @b
pop ebp edx ebx
jmp .palette_parsed
 
.24bpp_palette:
@@:
lodsd
dec esi
and eax,0xFFFFFF
; bswap eax
; shr eax,8
and eax, 0xffffff
stosd
loop @b
pop eax
.palette_parsed:
mov edi,[eax+Image.Data]
imul ebx,[IMGwidth] ;ebx=width*height
 
mov edx,[IMGbpp]
add edx,7
shr edx,3 ;edx=bytes per pixel
mov dh,dl ;dh=dl=bytes per pixel
 
mov edi, [ebx + Image.Data]
mov ebx, [width]
imul ebx, [height]
mov edx, [bytes_per_pixel]
mov eax,[_data]
cmp byte[eax+2],9
jb .not_an_rle
.tga_read_rle_pixel:
cmp [DupPixelCount],0 ;Duplicate previously read pixel?
jg .duplicate_previously_read_pixel
dec [TgaBlockCount] ;Decrement pixels remaining in block
jns .read_non_rle_pixel
test byte[eax + tga_header.image_type], 0x08
jz .uncompressed
.next_rle_packet:
xor eax,eax
lodsb
test al,al ;Start of duplicate-pixel block?
jns .2
and al,0x7f
mov [DupPixelCount],eax ;Number of duplications after this one
and [TgaBlockCount],0 ;Then read new block header
jmp .read_non_rle_pixel
.2:
mov dword[TgaBlockCount],eax
.read_non_rle_pixel:
xor eax,eax
mov dl,dh
btr ax, 7 ; Run-length packet?
jnc .raw_packet
add eax, 1
sub ebx, eax
@@:
shl eax,8
lodsb
dec dl
mov ecx, edx
rep movsb
sub esi, edx
sub eax, 1
jnz @b
cmp dh,3
jne .put_pixel
bswap eax
shr eax,8
jmp .put_pixel
.duplicate_previously_read_pixel:
dec [DupPixelCount]
.put_pixel:
mov dl,dh
push eax
@@:
stosb
shr eax,8
dec dl
jnz @b
pop eax
dec ebx
jnz .tga_read_rle_pixel
jmp .locret
.not_an_rle:
movzx edx,dl ;dh contains bpp too (for decoding needs)
add esi, edx
test ebx, ebx
jnz .next_rle_packet
jmp .done
.raw_packet:
mov ecx, eax
add ecx, 1
sub ebx, ecx
imul ecx, edx
rep movsb
test ebx, ebx
jnz .next_rle_packet
.uncompressed:
imul edx,ebx
mov ecx,edx
rep movsb ;just copy the image
.locret:
popad
rep movsb
.done:
xor ebx, ebx
mov esi, [_data]
test byte[esi + tga_header.image_spec.descriptor], TGA_START_TOP
jnz @f
or ebx, FLIP_VERTICAL
@@:
test byte[esi + tga_header.image_spec.descriptor], TGA_START_RIGHT
jz @f
or ebx, FLIP_HORIZONTAL
@@:
test ebx, ebx
jz @f
stdcall img.flip, [retvalue], ebx
@@:
pop edi esi ebx
mov eax, [retvalue]
ret
endp
 
230,7 → 271,6
ret
endp
 
 
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
246,5 → 286,3
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
 
;