Rev 1426 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1426 | Rev 3055 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | ;;================================================================================================;; |
1 | ;;================================================================================================;; |
2 | ;;//// tga.asm //// (c) Nable, 2007-2008 /////////////////////////////////////////////////////////;; |
2 | ;;//// tga.asm //// (c) Nable, 2007-2008, (c) dunkaist, 2012 /////////////////////////////////////;; |
3 | ;;================================================================================================;; |
3 | ;;================================================================================================;; |
4 | ;; ;; |
4 | ;; ;; |
5 | ;; This file is part of Common development libraries (Libs-Dev). ;; |
5 | ;; This file is part of Common development libraries (Libs-Dev). ;; |
6 | ;; ;; |
6 | ;; ;; |
7 | ;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;; |
7 | ;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;; |
Line 17... | Line 17... | ||
17 | ;; ;; |
17 | ;; ;; |
18 | ;;================================================================================================;; |
18 | ;;================================================================================================;; |
19 | ;; ;; |
19 | ;; ;; |
20 | ;; References: ;; |
20 | ;; References: ;; |
21 | ;; 1. Hiview 1.2 by Mohammad A. REZAEI ;; |
21 | ;; 1. Hiview 1.2 by Mohammad A. REZAEI ;; |
- | 22 | ;; 2. Truevision TGA FILE FORMAT SPECIFICATION Version 2.0 ;; |
|
- | 23 | ;; Technical Manual Version 2.2 January, 1991 ;; |
|
22 | ;; ;; |
24 | ;; ;; |
23 | ;;================================================================================================;; |
25 | ;;================================================================================================;; |
Line 24... | Line 26... | ||
24 | 26 | ||
Line 35... | Line 37... | ||
35 | ;< eax = false / true ;; |
37 | ;< eax = false / true ;; |
36 | ;;================================================================================================;; |
38 | ;;================================================================================================;; |
37 | push ebx |
39 | push ebx |
38 | cmp [_length], 18 |
40 | cmp [_length], 18 |
39 | jbe .nope |
41 | jbe .nope |
40 | mov eax, [_data] |
42 | mov ebx, [_data] |
41 | mov ebx,[eax+1] ;bl=cmatype,bh=subtype |
43 | mov eax, dword[ebx + tga_header.colormap_type] |
42 | cmp bl,1 ;cmatype is in [0..1] |
44 | cmp al, 1 |
43 | ja .nope |
45 | ja .nope |
44 | cmp bh,11 ;subtype is in [1..3] (non-rle) or in [9..11] (rle) |
46 | cmp ah, 11 |
45 | ja .nope |
47 | ja .nope |
46 | cmp bh,9 |
48 | cmp ah, 9 |
47 | jae .cont1 |
49 | jae .cont1 |
48 | cmp bh,3 |
50 | cmp ah, 3 |
49 | ja .nope |
51 | ja .nope |
50 | .cont1: ;continue testing |
52 | .cont1: |
51 | mov ebx,[eax+16] ;bl=bpp, bh=flags //image descriptor |
53 | mov eax, dword[ebx + tga_header.image_spec.depth] |
52 | test ebx,111b ;bpp must be 8, 15, 16, 24 or 32 |
54 | test eax, 111b ; bpp must be 8, 15, 16, 24 or 32 |
53 | jnz .maybe15 |
55 | jnz .maybe15 |
54 | shr bl,3 |
56 | shr al, 3 |
55 | cmp bl,4 |
57 | cmp al, 4 |
56 | ja .nope |
58 | ja .nope |
57 | jmp .cont2 |
59 | jmp .cont2 |
58 | .maybe15: |
60 | .maybe15: |
59 | cmp bl,15 |
61 | cmp al, 15 |
60 | jne .nope |
62 | jne .nope |
61 | .cont2: ;continue testing |
63 | .cont2: ; continue testing |
62 | test bh,tga.flags.interlace_type ;deinterlacing is not supported yet |
64 | movzx eax, byte[ebx + tga_header.colormap_spec.entry_size] ; palette bpp |
- | 65 | cmp eax, 0 |
|
63 | jnz .nope |
66 | je .yep |
64 | cmp byte[eax+7],24 ;test palette bpp - only 24 and 32 are supported |
67 | cmp eax, 16 |
65 | je .yep |
68 | je .yep |
- | 69 | cmp eax, 24 |
|
- | 70 | je .yep |
|
66 | cmp byte[eax+7],32 ;test palette bpp - only 24 and 32 are supported |
71 | cmp eax, 32 |
67 | je .yep |
72 | je .yep |
68 | .nope: |
73 | .nope: |
69 | xor eax, eax |
74 | xor eax, eax |
70 | pop ebx |
75 | pop ebx |
71 | ret |
76 | ret |
Line 86... | Line 91... | ||
86 | ;> _length = data length ;; |
91 | ;> _length = data length ;; |
87 | ;;------------------------------------------------------------------------------------------------;; |
92 | ;;------------------------------------------------------------------------------------------------;; |
88 | ;< eax = 0 (error) or pointer to image ;; |
93 | ;< eax = 0 (error) or pointer to image ;; |
89 | ;;================================================================================================;; |
94 | ;;================================================================================================;; |
90 | locals |
95 | locals |
91 | IMGwidth dd ? |
96 | width dd ? |
92 | IMGheight dd ? |
97 | height dd ? |
93 | IMGbpp dd ? |
- | |
94 | DupPixelCount dd ? |
98 | bytes_per_pixel dd ? |
95 | TgaBlockCount dd ? |
99 | retvalue dd ? |
96 | endl |
100 | endl |
97 | pushad |
101 | push ebx esi edi |
98 | cld ;paranoia |
- | |
99 | and [DupPixelCount],0 ;prepare variables |
- | |
100 | and [TgaBlockCount],0 ;prepare variables |
- | |
101 | mov eax,[_data] |
102 | mov ebx, [_data] |
102 | movzx esi,byte[eax] |
103 | movzx esi, byte[ebx] |
103 | lea esi,[esi+eax+18] ;skip comment and header |
104 | lea esi, [esi + ebx + sizeof.tga_header] ; skip comment and header |
104 | mov ebx,[eax+12] |
105 | mov edx, dword[ebx + tga_header.image_spec.width] |
105 | movzx ecx,bx ;ecx=width |
106 | movzx ecx, dx ; ecx = width |
106 | shr ebx,16 ;ebx=height |
107 | shr edx, 16 ; edx = height |
107 | mov [IMGwidth],ecx |
108 | mov [width], ecx |
108 | mov [IMGheight],ebx |
109 | mov [height], edx |
- | 110 | movzx eax, byte[ebx + tga_header.image_spec.depth] |
|
- | 111 | add eax, 7 |
|
- | 112 | shr eax, 3 |
|
- | 113 | mov [bytes_per_pixel], eax |
|
- | 114 | movzx eax, byte[ebx + tga_header.image_spec.depth] |
|
- | 115 | ||
- | 116 | cmp eax, 8 |
|
- | 117 | jne @f |
|
- | 118 | mov eax, Image.bpp8i |
|
- | 119 | jmp .type_defined |
|
- | 120 | @@: |
|
- | 121 | cmp eax, 15 |
|
- | 122 | jne @f |
|
109 | movzx edx,byte[eax+16] |
123 | mov eax, Image.bpp15 |
- | 124 | jmp .type_defined |
|
- | 125 | @@: |
|
110 | cmp edx,16 |
126 | cmp eax, 16 |
111 | jnz @f |
127 | jne @f |
112 | dec edx ;16bpp tga images are really 15bpp ARGB |
128 | mov eax, Image.bpp15 ; 16bpp tga images are really 15bpp ARGB |
- | 129 | jmp .type_defined |
|
113 | @@: |
130 | @@: |
- | 131 | cmp eax, 24 |
|
- | 132 | jne @f |
|
114 | sub edx, 16 - Image.bpp16 ; 15 -> Image.bpp15, 16 -> Image.bpp16 |
133 | mov eax, Image.bpp24 |
- | 134 | jmp .type_defined |
|
- | 135 | @@: |
|
- | 136 | cmp eax, 32 |
|
- | 137 | jne @f |
|
115 | mov [IMGbpp],edx |
138 | mov eax, Image.bpp32 |
- | 139 | jmp .type_defined |
|
- | 140 | @@: |
|
- | 141 | .type_defined: |
|
116 | stdcall img.create,ecx,ebx,edx |
142 | stdcall img.create, ecx, edx, eax |
117 | mov [esp+28],eax ;save return value |
143 | mov [retvalue], eax |
118 | test eax,eax ;failed to allocate? |
144 | test eax, eax ; failed to allocate? |
119 | jz .locret ;then exit |
145 | jz .done ; then exit |
120 | cmp edx,8 |
146 | mov ebx, eax |
- | 147 | cmp dword[ebx + Image.Type], Image.bpp8i |
|
121 | jne .palette_parsed |
148 | jne .palette_parsed |
122 | mov edi,[eax+Image.Palette] |
149 | mov edi, [ebx + Image.Palette] |
123 | mov ecx,[_data] |
150 | mov ecx, [_data] |
124 | cmp byte[ecx+2],3 ;we also have grayscale subtype |
151 | cmp byte[ecx + tga_header.image_type], 3 ; we also have grayscale subtype |
125 | jz .write_grayscale_palette ;that don't hold palette in file |
152 | jz .write_grayscale_palette ; that don't hold palette in file |
126 | cmp byte[ecx+2],11 |
153 | cmp byte[ecx + tga_header.image_type], 11 |
127 | jz .write_grayscale_palette |
154 | jz .write_grayscale_palette |
128 | mov dh,[ecx+7] ;size of colormap entries in bits |
155 | movzx eax, byte[ecx + tga_header.colormap_spec.entry_size] ; size of colormap entries in bits |
129 | movzx ecx,word[ecx+5] ;number of colormap entries |
156 | movzx ecx, word[ecx + tga_header.colormap_spec.colormap_length] ; number of colormap entries |
130 | cmp dh,24 |
157 | cmp eax, 24 |
131 | jz .skip_24bpp_palette ;test if colormap entries are 24bpp |
158 | je .24bpp_palette |
- | 159 | cmp eax, 16 |
|
- | 160 | je .16bpp_palette |
|
132 | rep movsd ;else they are 32 bpp |
161 | rep movsd ; else they are 32 bpp |
133 | jmp .palette_parsed |
162 | jmp .palette_parsed |
134 | .write_grayscale_palette: |
163 | .write_grayscale_palette: |
135 | push eax |
- | |
136 | mov ecx,0x100 |
164 | mov ecx, 0x100 |
137 | xor eax,eax |
165 | xor eax, eax |
138 | @@: |
166 | @@: |
139 | stosd |
167 | stosd |
140 | add eax,0x010101 |
168 | add eax, 0x010101 |
141 | loop @b |
169 | loop @b |
142 | pop eax |
- | |
143 | jmp .palette_parsed |
170 | jmp .palette_parsed |
- | 171 | .16bpp_palette: ; FIXME: code copypasted from img.do_rgb, should use img.convert |
|
144 | .skip_24bpp_palette: |
172 | push ebx edx ebp |
- | 173 | @@: |
|
- | 174 | movzx eax, word[esi] |
|
145 | push eax |
175 | mov ebx, eax |
- | 176 | add esi, 2 |
|
- | 177 | and eax, (0x1F) or (0x1F shl 10) |
|
- | 178 | and ebx, 0x1F shl 5 |
|
- | 179 | lea edx, [eax + eax] |
|
- | 180 | shr al, 2 |
|
- | 181 | mov ebp, ebx |
|
- | 182 | shr ebx, 2 |
|
- | 183 | shr ah, 4 |
|
- | 184 | shl dl, 2 |
|
- | 185 | shr ebp, 7 |
|
- | 186 | add eax, edx |
|
- | 187 | add ebx, ebp |
|
- | 188 | mov [edi], al |
|
- | 189 | mov [edi + 1], bl |
|
- | 190 | mov [edi + 2], ah |
|
- | 191 | add edi, 4 |
|
- | 192 | loop @b |
|
- | 193 | pop ebp edx ebx |
|
- | 194 | jmp .palette_parsed |
|
- | 195 | ||
- | 196 | .24bpp_palette: |
|
146 | @@: |
197 | @@: |
147 | lodsd |
198 | lodsd |
148 | dec esi |
199 | dec esi |
149 | and eax,0xFFFFFF |
200 | and eax, 0xffffff |
150 | ; bswap eax |
- | |
151 | ; shr eax,8 |
- | |
152 | stosd |
201 | stosd |
153 | loop @b |
202 | loop @b |
154 | pop eax |
- | |
155 | .palette_parsed: |
203 | .palette_parsed: |
156 | mov edi,[eax+Image.Data] |
204 | mov edi, [ebx + Image.Data] |
157 | imul ebx,[IMGwidth] ;ebx=width*height |
- | |
158 | - | ||
159 | mov edx,[IMGbpp] |
205 | mov ebx, [width] |
160 | add edx,7 |
206 | imul ebx, [height] |
161 | shr edx,3 ;edx=bytes per pixel |
207 | mov edx, [bytes_per_pixel] |
162 | mov dh,dl ;dh=dl=bytes per pixel |
- | |
163 | - | ||
164 | mov eax,[_data] |
208 | mov eax, [_data] |
165 | cmp byte[eax+2],9 |
209 | test byte[eax + tga_header.image_type], 0x08 |
166 | jb .not_an_rle |
210 | jz .uncompressed |
167 | .tga_read_rle_pixel: |
211 | .next_rle_packet: |
168 | cmp [DupPixelCount],0 ;Duplicate previously read pixel? |
- | |
169 | jg .duplicate_previously_read_pixel |
- | |
170 | dec [TgaBlockCount] ;Decrement pixels remaining in block |
- | |
171 | jns .read_non_rle_pixel |
- | |
172 | xor eax,eax |
212 | xor eax, eax |
173 | lodsb |
213 | lodsb |
174 | test al,al ;Start of duplicate-pixel block? |
- | |
175 | jns .2 |
- | |
176 | and al,0x7f |
- | |
177 | mov [DupPixelCount],eax ;Number of duplications after this one |
- | |
178 | and [TgaBlockCount],0 ;Then read new block header |
- | |
179 | jmp .read_non_rle_pixel |
- | |
180 | .2: |
- | |
181 | mov dword[TgaBlockCount],eax |
214 | btr ax, 7 ; Run-length packet? |
182 | .read_non_rle_pixel: |
215 | jnc .raw_packet |
183 | xor eax,eax |
216 | add eax, 1 |
184 | mov dl,dh |
217 | sub ebx, eax |
185 | @@: |
218 | @@: |
186 | shl eax,8 |
- | |
187 | lodsb |
- | |
188 | dec dl |
219 | mov ecx, edx |
189 | jnz @b |
- | |
190 | cmp dh,3 |
- | |
191 | jne .put_pixel |
- | |
192 | bswap eax |
- | |
193 | shr eax,8 |
- | |
194 | jmp .put_pixel |
- | |
195 | .duplicate_previously_read_pixel: |
- | |
196 | dec [DupPixelCount] |
- | |
197 | .put_pixel: |
- | |
198 | mov dl,dh |
220 | rep movsb |
199 | push eax |
221 | sub esi, edx |
200 | @@: |
- | |
201 | stosb |
- | |
202 | shr eax,8 |
222 | sub eax, 1 |
203 | dec dl |
- | |
204 | jnz @b |
223 | jnz @b |
205 | pop eax |
224 | add esi, edx |
206 | dec ebx |
225 | test ebx, ebx |
207 | jnz .tga_read_rle_pixel |
226 | jnz .next_rle_packet |
208 | jmp .locret |
227 | jmp .done |
209 | .not_an_rle: |
228 | .raw_packet: |
- | 229 | mov ecx, eax |
|
- | 230 | add ecx, 1 |
|
- | 231 | sub ebx, ecx |
|
- | 232 | imul ecx, edx |
|
- | 233 | rep movsb |
|
- | 234 | test ebx, ebx |
|
210 | movzx edx,dl ;dh contains bpp too (for decoding needs) |
235 | jnz .next_rle_packet |
- | 236 | .uncompressed: |
|
211 | imul edx,ebx |
237 | imul edx, ebx |
212 | mov ecx,edx |
238 | mov ecx, edx |
213 | rep movsb ;just copy the image |
239 | rep movsb |
214 | .locret: |
240 | .done: |
- | 241 | xor ebx, ebx |
|
- | 242 | mov esi, [_data] |
|
- | 243 | test byte[esi + tga_header.image_spec.descriptor], TGA_START_TOP |
|
- | 244 | jnz @f |
|
- | 245 | or ebx, FLIP_VERTICAL |
|
- | 246 | @@: |
|
- | 247 | test byte[esi + tga_header.image_spec.descriptor], TGA_START_RIGHT |
|
- | 248 | jz @f |
|
- | 249 | or ebx, FLIP_HORIZONTAL |
|
- | 250 | @@: |
|
- | 251 | test ebx, ebx |
|
215 | popad |
252 | jz @f |
- | 253 | stdcall img.flip, [retvalue], ebx |
|
- | 254 | @@: |
|
- | 255 | pop edi esi ebx |
|
- | 256 | mov eax, [retvalue] |
|
216 | ret |
257 | ret |
217 | endp |
258 | endp |
Line 218... | Line 259... | ||
218 | 259 | ||
219 | ;;================================================================================================;; |
260 | ;;================================================================================================;; |
Line 228... | Line 269... | ||
228 | ;;================================================================================================;; |
269 | ;;================================================================================================;; |
229 | xor eax, eax |
270 | xor eax, eax |
230 | ret |
271 | ret |
231 | endp |
272 | endp |
Line 232... | Line -... | ||
232 | - | ||
233 | 273 | ||
234 | ;;================================================================================================;; |
274 | ;;================================================================================================;; |
235 | ;;////////////////////////////////////////////////////////////////////////////////////////////////;; |
275 | ;;////////////////////////////////////////////////////////////////////////////////////////////////;; |
236 | ;;================================================================================================;; |
276 | ;;================================================================================================;; |
237 | ;! Below are private procs you should never call directly from your code ;; |
277 | ;! Below are private procs you should never call directly from your code ;; |
Line 244... | Line 284... | ||
244 | ;;================================================================================================;; |
284 | ;;================================================================================================;; |
245 | ;! Below is private data you should never use directly from your code ;; |
285 | ;! Below is private data you should never use directly from your code ;; |
246 | ;;================================================================================================;; |
286 | ;;================================================================================================;; |
247 | ;;////////////////////////////////////////////////////////////////////////////////////////////////;; |
287 | ;;////////////////////////////////////////////////////////////////////////////////////////////////;; |
248 | ;;================================================================================================;; |
288 | ;;================================================================================================;;>>>> |
249 | - | ||
250 | ;>>>> |
- | |
251 | 289 |