2009-05-24 18:47:14 +02:00
|
|
|
;;================================================================================================;;
|
2012-11-18 17:10:28 +01:00
|
|
|
;;//// tga.asm //// (c) Nable, 2007-2008, (c) dunkaist, 2012 /////////////////////////////////////;;
|
2009-05-24 18:47:14 +02:00
|
|
|
;;================================================================================================;;
|
|
|
|
;; ;;
|
|
|
|
;; 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 ;;
|
2012-11-18 17:10:28 +01:00
|
|
|
;; 2. Truevision TGA FILE FORMAT SPECIFICATION Version 2.0 ;;
|
|
|
|
;; Technical Manual Version 2.2 January, 1991 ;;
|
2009-05-24 18:47:14 +02:00
|
|
|
;; ;;
|
|
|
|
;;================================================================================================;;
|
|
|
|
|
|
|
|
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 ;;
|
|
|
|
;;================================================================================================;;
|
2012-11-18 17:10:28 +01:00
|
|
|
push ebx
|
2009-05-24 18:47:14 +02:00
|
|
|
cmp [_length], 18
|
|
|
|
jbe .nope
|
2012-11-18 17:10:28 +01:00
|
|
|
mov ebx, [_data]
|
|
|
|
mov eax, dword[ebx + tga_header.colormap_type]
|
|
|
|
cmp al, 1
|
2009-05-24 18:47:14 +02:00
|
|
|
ja .nope
|
2012-11-18 17:10:28 +01:00
|
|
|
cmp ah, 11
|
2009-05-24 18:47:14 +02:00
|
|
|
ja .nope
|
2012-11-18 17:10:28 +01:00
|
|
|
cmp ah, 9
|
2009-05-24 18:47:14 +02:00
|
|
|
jae .cont1
|
2012-11-18 17:10:28 +01:00
|
|
|
cmp ah, 3
|
2009-05-24 18:47:14 +02:00
|
|
|
ja .nope
|
2012-11-18 17:10:28 +01:00
|
|
|
.cont1:
|
|
|
|
mov eax, dword[ebx + tga_header.image_spec.depth]
|
|
|
|
test eax, 111b ; bpp must be 8, 15, 16, 24 or 32
|
2009-05-24 18:47:14 +02:00
|
|
|
jnz .maybe15
|
2012-11-18 17:10:28 +01:00
|
|
|
shr al, 3
|
|
|
|
cmp al, 4
|
2009-05-24 18:47:14 +02:00
|
|
|
ja .nope
|
|
|
|
jmp .cont2
|
2012-11-18 17:10:28 +01:00
|
|
|
.maybe15:
|
|
|
|
cmp al, 15
|
2009-05-24 18:47:14 +02:00
|
|
|
jne .nope
|
2012-11-18 17:10:28 +01:00
|
|
|
.cont2: ; continue testing
|
|
|
|
movzx eax, byte[ebx + tga_header.colormap_spec.entry_size] ; palette bpp
|
|
|
|
cmp eax, 0
|
|
|
|
je .yep
|
|
|
|
cmp eax, 16
|
2009-05-24 18:47:14 +02:00
|
|
|
je .yep
|
2012-11-18 17:10:28 +01:00
|
|
|
cmp eax, 24
|
2009-05-24 18:47:14 +02:00
|
|
|
je .yep
|
2012-11-18 17:10:28 +01:00
|
|
|
cmp eax, 32
|
|
|
|
je .yep
|
|
|
|
.nope:
|
2009-05-24 18:47:14 +02:00
|
|
|
xor eax, eax
|
2012-11-18 17:10:28 +01:00
|
|
|
pop ebx
|
2009-05-24 18:47:14 +02:00
|
|
|
ret
|
|
|
|
|
2012-11-18 17:10:28 +01:00
|
|
|
.yep:
|
2009-05-24 18:47:14 +02:00
|
|
|
xor eax, eax
|
|
|
|
inc eax
|
2012-11-18 17:10:28 +01:00
|
|
|
pop ebx
|
2009-05-24 18:47:14 +02:00
|
|
|
ret
|
|
|
|
endp
|
|
|
|
|
|
|
|
;;================================================================================================;;
|
2009-06-03 23:12:49 +02:00
|
|
|
proc img.decode.tga _data, _length, _options ;////////////////////////////////////////////////////;;
|
2009-05-24 18:47:14 +02:00
|
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
|
|
;? 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
|
2012-11-18 17:10:28 +01:00
|
|
|
width dd ?
|
|
|
|
height dd ?
|
|
|
|
bytes_per_pixel dd ?
|
|
|
|
retvalue dd ?
|
2009-05-24 18:47:14 +02:00
|
|
|
endl
|
2012-11-18 17:10:28 +01:00
|
|
|
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
|
|
|
|
@@:
|
|
|
|
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 .done ; then exit
|
|
|
|
mov ebx, eax
|
|
|
|
cmp dword[ebx + Image.Type], Image.bpp8i
|
2009-05-24 18:47:14 +02:00
|
|
|
jne .palette_parsed
|
2012-11-18 17:10:28 +01:00
|
|
|
mov edi, [ebx + Image.Palette]
|
|
|
|
mov ecx, [_data]
|
|
|
|
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 + tga_header.image_type], 11
|
2009-05-24 18:47:14 +02:00
|
|
|
jz .write_grayscale_palette
|
2012-11-18 17:10:28 +01:00
|
|
|
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
|
2009-05-24 18:47:14 +02:00
|
|
|
jmp .palette_parsed
|
2012-11-18 17:10:28 +01:00
|
|
|
.write_grayscale_palette:
|
|
|
|
mov ecx, 0x100
|
|
|
|
xor eax, eax
|
|
|
|
@@:
|
2009-05-24 18:47:14 +02:00
|
|
|
stosd
|
2012-11-18 17:10:28 +01:00
|
|
|
add eax, 0x010101
|
|
|
|
loop @b
|
2009-05-24 18:47:14 +02:00
|
|
|
jmp .palette_parsed
|
2012-11-18 17:10:28 +01:00
|
|
|
.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:
|
|
|
|
@@:
|
2009-05-24 18:47:14 +02:00
|
|
|
lodsd
|
2012-11-18 17:10:28 +01:00
|
|
|
dec esi
|
|
|
|
and eax, 0xffffff
|
2009-05-24 18:47:14 +02:00
|
|
|
stosd
|
2012-11-18 17:10:28 +01:00
|
|
|
loop @b
|
|
|
|
.palette_parsed:
|
|
|
|
mov edi, [ebx + Image.Data]
|
|
|
|
mov ebx, [width]
|
|
|
|
imul ebx, [height]
|
|
|
|
mov edx, [bytes_per_pixel]
|
|
|
|
mov eax, [_data]
|
|
|
|
test byte[eax + tga_header.image_type], 0x08
|
|
|
|
jz .uncompressed
|
|
|
|
.next_rle_packet:
|
|
|
|
xor eax, eax
|
|
|
|
lodsb
|
|
|
|
btr ax, 7 ; Run-length packet?
|
|
|
|
jnc .raw_packet
|
|
|
|
add eax, 1
|
|
|
|
sub ebx, eax
|
|
|
|
@@:
|
|
|
|
mov ecx, edx
|
|
|
|
rep movsb
|
|
|
|
sub esi, edx
|
|
|
|
sub eax, 1
|
|
|
|
jnz @b
|
|
|
|
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
|
|
|
|
.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]
|
2009-05-24 18:47:14 +02:00
|
|
|
ret
|
|
|
|
endp
|
|
|
|
|
|
|
|
;;================================================================================================;;
|
2009-06-03 23:12:49 +02:00
|
|
|
proc img.encode.tga _img, _p_length, _options ;///////////////////////////////////////////////////;;
|
2009-05-24 18:47:14 +02:00
|
|
|
;;------------------------------------------------------------------------------------------------;;
|
|
|
|
;? 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 ;;
|
|
|
|
;;================================================================================================;;
|
|
|
|
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
|
|
|
;;================================================================================================;;
|