Rev 139 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
552 | diamond | 1 | ; GIF LITE v3.0 by Willow |
134 | diamond | 2 | ; Written in pure assembler by Ivushkin Andrey aka Willow |
552 | diamond | 3 | ; Modified by Diamond |
134 | diamond | 4 | ; |
5 | ; This include file will contain functions to handle GIF image format |
||
6 | ; |
||
7 | ; Created: August 15, 2004 |
||
552 | diamond | 8 | ; Last changed: June 24, 2007 |
134 | diamond | 9 | |
552 | diamond | 10 | ; Requires kglobals.inc (iglobal/uglobal macro) |
11 | ; (program must 'include "kglobals.inc"' and say 'IncludeUGlobal' |
||
12 | ; somewhere in uninitialized data area). |
||
134 | diamond | 13 | |
552 | diamond | 14 | ; Configuration: [changed from program which includes this file] |
15 | ; 1. The constant COLOR_ORDER: must be one of |
||
16 | ; PALETTE - for 8-bit image with palette (sysfunction 65) |
||
17 | ; MENUETOS - for MenuetOS and KolibriOS color order (sysfunction 7) |
||
18 | ; OTHER - for standard color order |
||
19 | ; 2. Define constant GIF_SUPPORT_INTERLACED if you want to support interlaced |
||
20 | ; GIFs. |
||
21 | ; 3. Single image mode vs multiple image mode: |
||
22 | ; if the program defines the variable 'gif_img_count' of type dword |
||
23 | ; somewhere, ReadGIF will enter multiple image mode: gif_img_count |
||
24 | ; will be initialized with image count, output format is GIF_list, |
||
25 | ; the function GetGIFinfo retrieves Nth image info. Otherwise, ReadGIF |
||
26 | ; uses single image mode: exit after end of first image, output is |
||
27 | ; |
||
28 | |||
29 | if ~ (COLOR_ORDER in |
||
134 | diamond | 30 | ; This message may not appear under MenuetOS, so watch... |
552 | diamond | 31 | display 'Please define COLOR_ORDER: PALETTE, MENUETOS or OTHER',13,10 |
134 | diamond | 32 | end if |
33 | |||
552 | diamond | 34 | if defined gif_img_count |
134 | diamond | 35 | ; virtual structure, used internally |
36 | |||
552 | diamond | 37 | struct GIF_list |
38 | NextImg rd 1 |
||
39 | Left rw 1 |
||
40 | Top rw 1 |
||
41 | Width rw 1 |
||
42 | Height rw 1 |
||
43 | Delay rd 1 |
||
44 | Displacement rd 1 ; 0 = not specified |
||
45 | ; 1 = do not dispose |
||
46 | ; 2 = restore to background color |
||
47 | ; 3 = restore to previous |
||
48 | if COLOR_ORDER eq PALETTE |
||
49 | Image rd 1 |
||
50 | end if |
||
51 | ends |
||
134 | diamond | 52 | |
552 | diamond | 53 | struct GIF_info |
54 | Left rw 1 |
||
55 | Top rw 1 |
||
56 | Width rw 1 |
||
57 | Height rw 1 |
||
58 | Delay rd 1 |
||
59 | Displacement rd 1 |
||
60 | if COLOR_ORDER eq PALETTE |
||
61 | Palette rd 1 |
||
62 | end if |
||
63 | ends |
||
134 | diamond | 64 | |
65 | ; **************************************** |
||
66 | ; FUNCTION GetGIFinfo - retrieve Nth image info |
||
67 | ; **************************************** |
||
68 | ; in: |
||
69 | ; esi - pointer to image list header |
||
70 | ; ecx - image_index (0...img_count-1) |
||
71 | ; edi - pointer to GIF_info structure to be filled |
||
72 | |||
73 | ; out: |
||
74 | ; eax - pointer to RAW data, or 0, if error |
||
75 | |||
76 | GetGIFinfo: |
||
77 | push esi ecx edi |
||
78 | xor eax,eax |
||
79 | jecxz .eloop |
||
80 | .lp: |
||
81 | mov esi,[esi] |
||
82 | test esi,esi |
||
83 | jz .error |
||
84 | loop .lp |
||
85 | .eloop: |
||
552 | diamond | 86 | lodsd |
134 | diamond | 87 | movsd |
88 | movsd |
||
552 | diamond | 89 | movsd |
90 | movsd |
||
91 | if COLOR_ORDER eq PALETTE |
||
92 | lodsd |
||
93 | mov [edi],esi |
||
94 | else |
||
134 | diamond | 95 | mov eax,esi |
552 | diamond | 96 | end if |
134 | diamond | 97 | .error: |
98 | pop edi ecx esi |
||
99 | ret |
||
100 | |||
552 | diamond | 101 | end if |
102 | |||
103 | _null fix 0x1000 |
||
104 | |||
134 | diamond | 105 | ; **************************************** |
106 | ; FUNCTION ReadGIF - unpacks GIF image |
||
107 | ; **************************************** |
||
108 | ; in: |
||
109 | ; esi - pointer to GIF file in memory |
||
110 | ; edi - pointer to output image list |
||
111 | |||
112 | ; out: |
||
113 | ; eax - 0, all OK; |
||
114 | ; eax - 1, invalid signature; |
||
115 | ; eax >=8, unsupported image attributes |
||
116 | ; |
||
117 | |||
118 | ReadGIF: |
||
119 | push esi edi |
||
120 | mov [.cur_info],edi |
||
121 | xor eax,eax |
||
122 | mov [.globalColor],eax |
||
552 | diamond | 123 | if defined gif_img_count |
124 | mov [gif_img_count],eax |
||
125 | mov [.anim_delay],eax |
||
126 | mov [.anim_disp],eax |
||
127 | end if |
||
134 | diamond | 128 | inc eax |
129 | cmp dword[esi],'GIF8' |
||
139 | diamond | 130 | jne .ex ; signature |
134 | diamond | 131 | mov ecx,[esi+0xa] |
132 | add esi,0xd |
||
133 | mov edi,esi |
||
552 | diamond | 134 | test cl,cl |
135 | jns .nextblock |
||
134 | diamond | 136 | mov [.globalColor],esi |
137 | call .Gif_skipmap |
||
138 | .nextblock: |
||
139 | cmp byte[edi],0x21 |
||
140 | jne .noextblock |
||
141 | inc edi |
||
552 | diamond | 142 | if defined gif_img_count |
134 | diamond | 143 | cmp byte[edi],0xf9 ; Graphic Control Ext |
144 | jne .no_gc |
||
552 | diamond | 145 | movzx eax,word [edi+3] |
146 | mov [.anim_delay],eax |
||
147 | mov al,[edi+2] |
||
148 | shr al,2 |
||
149 | and eax,7 |
||
150 | mov [.anim_disp],eax |
||
134 | diamond | 151 | add edi,7 |
152 | jmp .nextblock |
||
153 | .no_gc: |
||
552 | diamond | 154 | end if |
134 | diamond | 155 | inc edi |
156 | .block_skip: |
||
157 | movzx eax,byte[edi] |
||
158 | lea edi,[edi+eax+1] |
||
552 | diamond | 159 | test eax,eax |
134 | diamond | 160 | jnz .block_skip |
161 | jmp .nextblock |
||
162 | .noextblock: |
||
552 | diamond | 163 | mov al,8 |
134 | diamond | 164 | cmp byte[edi],0x2c ; image beginning |
139 | diamond | 165 | jne .ex |
552 | diamond | 166 | if defined gif_img_count |
167 | inc [gif_img_count] |
||
168 | end if |
||
134 | diamond | 169 | inc edi |
170 | mov esi,[.cur_info] |
||
552 | diamond | 171 | if defined gif_img_count |
134 | diamond | 172 | add esi,4 |
552 | diamond | 173 | end if |
134 | diamond | 174 | xchg esi,edi |
552 | diamond | 175 | if defined GIF_SUPPORT_INTERLACED |
176 | movzx ecx,word[esi+4] |
||
177 | mov [.width],ecx |
||
178 | movzx eax,word[esi+6] |
||
179 | imul eax,ecx |
||
180 | if ~(COLOR_ORDER eq PALETTE) |
||
181 | lea eax,[eax*3] |
||
182 | end if |
||
183 | mov [.img_end],eax |
||
184 | inc eax |
||
185 | mov [.row_end],eax |
||
186 | and [.pass],0 |
||
187 | test byte[esi+8],40h |
||
188 | jz @f |
||
189 | if ~(COLOR_ORDER eq PALETTE) |
||
190 | lea ecx,[ecx*3] |
||
191 | end if |
||
192 | mov [.row_end],ecx |
||
193 | @@: |
||
194 | end if |
||
195 | if defined gif_img_count |
||
134 | diamond | 196 | movsd |
197 | movsd |
||
552 | diamond | 198 | mov eax,[.anim_delay] |
199 | stosd |
||
200 | mov eax,[.anim_disp] |
||
201 | stosd |
||
202 | else |
||
203 | movzx eax,word[esi+4] |
||
204 | stosd |
||
205 | movzx eax,word[esi+6] |
||
206 | stosd |
||
207 | add esi,8 |
||
208 | end if |
||
134 | diamond | 209 | push edi |
552 | diamond | 210 | mov ecx,[esi] |
134 | diamond | 211 | inc esi |
552 | diamond | 212 | test cl,cl |
213 | js .uselocal |
||
134 | diamond | 214 | push [.globalColor] |
215 | mov edi,esi |
||
216 | jmp .setPal |
||
217 | .uselocal: |
||
218 | call .Gif_skipmap |
||
219 | push esi |
||
220 | .setPal: |
||
221 | movzx ecx,byte[edi] |
||
222 | inc ecx |
||
223 | mov [.codesize],ecx |
||
224 | dec ecx |
||
552 | diamond | 225 | if ~(COLOR_ORDER eq PALETTE) |
134 | diamond | 226 | pop [.Palette] |
552 | diamond | 227 | end if |
134 | diamond | 228 | lea esi,[edi+1] |
552 | diamond | 229 | mov edi,.gif_workarea |
134 | diamond | 230 | xor eax,eax |
231 | lodsb ; eax - block_count |
||
232 | add eax,esi |
||
233 | mov [.block_ofs],eax |
||
234 | mov [.bit_count],8 |
||
235 | mov eax,1 |
||
236 | shl eax,cl |
||
237 | mov [.CC],eax |
||
552 | diamond | 238 | mov ecx,eax |
134 | diamond | 239 | inc eax |
240 | mov [.EOI],eax |
||
241 | mov eax, _null shl 16 |
||
242 | .filltable: |
||
243 | stosd |
||
244 | inc eax |
||
245 | loop .filltable |
||
552 | diamond | 246 | if COLOR_ORDER eq PALETTE |
247 | pop eax |
||
134 | diamond | 248 | pop edi |
552 | diamond | 249 | push edi |
250 | scasd |
||
251 | push esi |
||
252 | mov esi,eax |
||
253 | mov ecx,[.CC] |
||
254 | @@: |
||
255 | lodsd |
||
256 | dec esi |
||
257 | bswap eax |
||
258 | shr eax,8 |
||
259 | stosd |
||
260 | loop @b |
||
261 | pop esi |
||
262 | pop eax |
||
263 | mov [eax],edi |
||
264 | else |
||
265 | pop edi |
||
266 | end if |
||
267 | if defined GIF_SUPPORT_INTERLACED |
||
134 | diamond | 268 | mov [.img_start],edi |
552 | diamond | 269 | add [.img_end],edi |
270 | add [.row_end],edi |
||
271 | end if |
||
134 | diamond | 272 | .reinit: |
273 | mov edx,[.EOI] |
||
274 | inc edx |
||
275 | push [.codesize] |
||
276 | pop [.compsize] |
||
277 | call .Gif_get_sym |
||
278 | cmp eax,[.CC] |
||
279 | je .reinit |
||
280 | call .Gif_output |
||
281 | .cycle: |
||
282 | movzx ebx,ax |
||
283 | call .Gif_get_sym |
||
284 | cmp eax,edx |
||
285 | jae .notintable |
||
286 | cmp eax,[.CC] |
||
287 | je .reinit |
||
288 | cmp eax,[.EOI] |
||
289 | je .end |
||
290 | call .Gif_output |
||
291 | .add: |
||
552 | diamond | 292 | mov dword [.gif_workarea+edx*4],ebx |
134 | diamond | 293 | cmp edx,0xFFF |
294 | jae .cycle |
||
295 | inc edx |
||
296 | bsr ebx,edx |
||
297 | cmp ebx,[.compsize] |
||
298 | jne .noinc |
||
299 | inc [.compsize] |
||
300 | .noinc: |
||
301 | jmp .cycle |
||
302 | .notintable: |
||
303 | push eax |
||
304 | mov eax,ebx |
||
305 | call .Gif_output |
||
306 | push ebx |
||
307 | movzx eax,bx |
||
308 | call .Gif_output |
||
309 | pop ebx eax |
||
310 | jmp .add |
||
311 | .end: |
||
552 | diamond | 312 | if defined GIF_SUPPORT_INTERLACED |
313 | mov edi,[.img_end] |
||
314 | end if |
||
315 | if defined gif_img_count |
||
134 | diamond | 316 | mov eax,[.cur_info] |
317 | mov [eax],edi |
||
318 | mov [.cur_info],edi |
||
319 | add esi,2 |
||
320 | xchg esi,edi |
||
321 | .nxt: |
||
322 | cmp byte[edi],0 |
||
323 | jnz .continue |
||
324 | inc edi |
||
325 | jmp .nxt |
||
326 | .continue: |
||
327 | cmp byte[edi],0x3b |
||
328 | jne .nextblock |
||
552 | diamond | 329 | xchg esi,edi |
330 | and dword [eax],0 |
||
331 | end if |
||
134 | diamond | 332 | xor eax,eax |
333 | .ex: |
||
334 | pop edi esi |
||
335 | ret |
||
336 | |||
337 | .Gif_skipmap: |
||
338 | ; in: ecx - image descriptor, esi - pointer to colormap |
||
339 | ; out: edi - pointer to area after colormap |
||
340 | |||
341 | and ecx,111b |
||
342 | inc ecx ; color map size |
||
343 | mov ebx,1 |
||
344 | shl ebx,cl |
||
345 | lea ebx,[ebx*2+ebx] |
||
346 | lea edi,[esi+ebx] |
||
347 | ret |
||
348 | |||
349 | .Gif_get_sym: |
||
350 | mov ecx,[.compsize] |
||
351 | push ecx |
||
352 | xor eax,eax |
||
353 | .shift: |
||
354 | ror byte[esi],1 |
||
355 | rcr eax,1 |
||
356 | dec [.bit_count] |
||
357 | jnz .loop1 |
||
358 | inc esi |
||
359 | cmp esi,[.block_ofs] |
||
360 | jb .noblock |
||
361 | push eax |
||
362 | xor eax,eax |
||
363 | lodsb |
||
364 | test eax,eax |
||
365 | jnz .nextbl |
||
366 | mov eax,[.EOI] |
||
367 | sub esi,2 |
||
368 | add esp,8 |
||
369 | jmp .exx |
||
370 | .nextbl: |
||
371 | add eax,esi |
||
372 | mov [.block_ofs],eax |
||
373 | pop eax |
||
374 | .noblock: |
||
375 | mov [.bit_count],8 |
||
376 | .loop1: |
||
377 | loop .shift |
||
378 | pop ecx |
||
379 | rol eax,cl |
||
380 | .exx: |
||
381 | xor ecx,ecx |
||
382 | ret |
||
383 | |||
384 | .Gif_output: |
||
385 | push esi eax edx |
||
552 | diamond | 386 | mov edx,.gif_workarea |
134 | diamond | 387 | .next: |
388 | push word[edx+eax*4] |
||
389 | mov ax,word[edx+eax*4+2] |
||
390 | inc ecx |
||
391 | cmp ax,_null |
||
392 | jnz .next |
||
393 | shl ebx,16 |
||
394 | mov bx,[esp] |
||
395 | .loop2: |
||
396 | pop ax |
||
397 | |||
552 | diamond | 398 | if COLOR_ORDER eq PALETTE |
399 | stosb |
||
400 | else |
||
401 | lea esi,[eax+eax*2] |
||
402 | add esi,[.Palette] |
||
134 | diamond | 403 | |
404 | if COLOR_ORDER eq MENUETOS |
||
405 | mov esi,[esi] |
||
406 | bswap esi |
||
407 | shr esi,8 |
||
408 | mov [edi],esi |
||
409 | add edi,3 |
||
410 | else |
||
411 | movsb |
||
552 | diamond | 412 | movsb |
413 | movsb |
||
134 | diamond | 414 | end if |
552 | diamond | 415 | end if |
134 | diamond | 416 | |
552 | diamond | 417 | if defined GIF_SUPPORT_INTERLACED |
418 | cmp edi,[.row_end] |
||
419 | jb .norowend |
||
420 | mov eax,[.width] |
||
421 | if ~(COLOR_ORDER eq PALETTE) |
||
422 | lea eax,[eax*3] |
||
423 | end if |
||
424 | push eax |
||
425 | sub edi,eax |
||
426 | add eax,eax |
||
427 | cmp [.pass],3 |
||
428 | jz @f |
||
429 | add eax,eax |
||
430 | cmp [.pass],2 |
||
431 | jz @f |
||
432 | add eax,eax |
||
433 | @@: |
||
434 | add edi,eax |
||
435 | pop eax |
||
436 | cmp edi,[.img_end] |
||
437 | jb .nextrow |
||
438 | mov edi,[.img_start] |
||
439 | inc [.pass] |
||
440 | add edi,eax |
||
441 | cmp [.pass],3 |
||
442 | jz @f |
||
443 | add edi,eax |
||
444 | cmp [.pass],2 |
||
445 | jz @f |
||
446 | add edi,eax |
||
447 | add edi,eax |
||
448 | @@: |
||
449 | .nextrow: |
||
450 | add eax,edi |
||
451 | mov [.row_end],eax |
||
452 | xor eax,eax |
||
453 | .norowend: |
||
454 | end if |
||
455 | |||
134 | diamond | 456 | loop .loop2 |
457 | pop edx eax esi |
||
458 | ret |
||
459 | |||
552 | diamond | 460 | uglobal |
461 | align 4 |
||
462 | ReadGIF.globalColor rd 1 |
||
463 | ReadGIF.cur_info rd 1 ; image table pointer |
||
464 | ReadGIF.codesize rd 1 |
||
465 | ReadGIF.compsize rd 1 |
||
466 | ReadGIF.bit_count rd 1 |
||
467 | ReadGIF.CC rd 1 |
||
468 | ReadGIF.EOI rd 1 |
||
469 | if ~(COLOR_ORDER eq PALETTE) |
||
470 | ReadGIF.Palette rd 1 |
||
471 | end if |
||
472 | ReadGIF.block_ofs rd 1 |
||
473 | if defined GIF_SUPPORT_INTERLACED |
||
474 | ReadGIF.row_end rd 1 |
||
475 | ReadGIF.img_end rd 1 |
||
476 | ReadGIF.img_start rd 1 |
||
477 | ReadGIF.pass rd 1 |
||
478 | ReadGIF.width rd 1 |
||
479 | end if |
||
480 | if defined gif_img_count |
||
481 | ReadGIF.anim_delay rd 1 |
||
482 | ReadGIF.anim_disp rd 1 |
||
483 | end if |
||
484 | ReadGIF.gif_workarea rb 16*1024 |
||
485 | endg |