f705611d81
* programs which use libs-dev updated accordingly * libimg: support for .ico and .cur files (icons and cursors) * kiv: show many different images in one file in one row git-svn-id: svn://kolibrios.org@1102 a494cfbc-eb01-0410-851d-a64ba20cac60
250 lines
10 KiB
NASM
250 lines
10 KiB
NASM
;;================================================================================================;;
|
|
;;//// tga.asm //// (c) Nable, 2007-2008 /////////////////////////////////////////////////////////;;
|
|
;;================================================================================================;;
|
|
;; ;;
|
|
;; This file is part of Common development libraries (Libs-Dev). ;;
|
|
;; ;;
|
|
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
|
|
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
|
|
;; of the License, or (at your option) any later version. ;;
|
|
;; ;;
|
|
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;;
|
|
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;
|
|
;; Lesser General Public License for more details. ;;
|
|
;; ;;
|
|
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev. ;;
|
|
;; If not, see <http://www.gnu.org/licenses/>. ;;
|
|
;; ;;
|
|
;;================================================================================================;;
|
|
;; ;;
|
|
;; References: ;;
|
|
;; 1. Hiview 1.2 by Mohammad A. REZAEI ;;
|
|
;; ;;
|
|
;;================================================================================================;;
|
|
|
|
include 'tga.inc'
|
|
|
|
;;================================================================================================;;
|
|
proc img.is.tga _data, _length ;//////////////////////////////////////////////////////////////////;;
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
;? Determine if raw data could be decoded (is in Targa format) ;;
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
;> _data = raw data as read from file/stream ;;
|
|
;> _length = data length ;;
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
;< eax = false / true ;;
|
|
;;================================================================================================;;
|
|
cmp [_length], 18
|
|
jbe .nope
|
|
mov eax, [_data]
|
|
push ebx
|
|
mov ebx,[eax+1] ;bl=cmatype,bh=subtype
|
|
cmp bl,1 ;cmatype is in [0..1]
|
|
ja .nope
|
|
cmp bh,11 ;subtype is in [1..3] (non-rle) or in [9..11] (rle)
|
|
ja .nope
|
|
cmp bh,9
|
|
jae .cont1
|
|
cmp bh,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
|
|
jnz .maybe15
|
|
shr bl,3
|
|
cmp bl,4
|
|
ja .nope
|
|
jmp .cont2
|
|
.maybe15:
|
|
cmp bl,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
|
|
je .yep
|
|
cmp byte[eax+7],32 ;test palette bpp - only 24 and 32 are supported
|
|
je .yep
|
|
.nope:
|
|
xor eax, eax
|
|
pop ebx
|
|
ret
|
|
|
|
.yep:
|
|
xor eax, eax
|
|
inc eax
|
|
pop ebx
|
|
ret
|
|
endp
|
|
|
|
;;================================================================================================;;
|
|
proc img.decode.tga _data, _length, _options ;////////////////////////////////////////////////////;;
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
;? Decode data into image if it contains correctly formed raw data in Targa format ;;
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
;> _data = raw data as read from file/stream ;;
|
|
;> _length = data length ;;
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
;< eax = 0 (error) or pointer to image ;;
|
|
;;================================================================================================;;
|
|
locals
|
|
IMGwidth dd ?
|
|
IMGheight dd ?
|
|
IMGbpp dd ?
|
|
DupPixelCount dd ?
|
|
TgaBlockCount 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
|
|
@@:
|
|
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
|
|
test eax,eax ;failed to allocate?
|
|
jz .locret ;then exit
|
|
cmp edx,8
|
|
jne .palette_parsed
|
|
mov edi,[eax+Image.Palette]
|
|
mov ecx,[_data]
|
|
cmp byte[ecx+2],3 ;we also have grayscale subtype
|
|
jz .write_grayscale_palette ;that don't hold palette in file
|
|
cmp byte[ecx+2],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
|
|
rep movsd ;else they are 32 bpp
|
|
jmp .palette_parsed
|
|
.write_grayscale_palette:
|
|
push eax
|
|
mov ecx,0x100
|
|
xor eax,eax
|
|
@@:
|
|
stosd
|
|
add eax,0x010101
|
|
loop @b
|
|
pop eax
|
|
jmp .palette_parsed
|
|
.skip_24bpp_palette:
|
|
push eax
|
|
@@:
|
|
lodsd
|
|
dec esi
|
|
and eax,0xFFFFFF
|
|
; bswap eax
|
|
; shr eax,8
|
|
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 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
|
|
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
|
|
@@:
|
|
shl eax,8
|
|
lodsb
|
|
dec dl
|
|
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)
|
|
imul edx,ebx
|
|
mov ecx,edx
|
|
rep movsb ;just copy the image
|
|
.locret:
|
|
popad
|
|
ret
|
|
endp
|
|
|
|
;;================================================================================================;;
|
|
proc img.encode.tga _img, _p_length, _options ;///////////////////////////////////////////////////;;
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
;? Encode image into raw data in Targa format ;;
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
;> _img = pointer to image ;;
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
;< eax = 0 (error) or pointer to encoded data ;;
|
|
;< _p_length = encoded data length ;;
|
|
;;================================================================================================;;
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
|
|
;;================================================================================================;;
|
|
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
|
;;================================================================================================;;
|
|
;! Below are private procs you should never call directly from your code ;;
|
|
;;================================================================================================;;
|
|
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
|
;;================================================================================================;;
|
|
|
|
;;================================================================================================;;
|
|
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
|
;;================================================================================================;;
|
|
;! Below is private data you should never use directly from your code ;;
|
|
;;================================================================================================;;
|
|
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
|
;;================================================================================================;;
|
|
|
|
; |