Subversion Repositories Kolibri OS

Rev

Rev 109 | 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
51 mikedld 2
; Written in pure assembler by Ivushkin Andrey aka Willow
552 diamond 3
; Modified by Diamond
51 mikedld 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
51 mikedld 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).
51 mikedld 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 )
51 mikedld 30
; This message may not appear under MenuetOS, so watch...
552 diamond 31
  display 'Please define COLOR_ORDER: PALETTE, MENUETOS or OTHER',13,10
51 mikedld 32
end if
33
 
552 diamond 34
if defined gif_img_count
51 mikedld 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
51 mikedld 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
51 mikedld 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
51 mikedld 87
    movsd
88
    movsd
552 diamond 89
    movsd
90
    movsd
91
if COLOR_ORDER eq PALETTE
92
    lodsd
93
    mov   [edi],esi
94
else
51 mikedld 95
    mov   eax,esi
552 diamond 96
end if
51 mikedld 97
  .error:
98
    pop   edi ecx esi
99
    ret
100
 
552 diamond 101
end if
102
 
103
_null fix 0x1000
104
 
51 mikedld 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
51 mikedld 128
    inc  eax
129
    cmp  dword[esi],'GIF8'
552 diamond 130
    jne  .ex            ; signature
51 mikedld 131
    mov  ecx,[esi+0xa]
132
    add  esi,0xd
133
    mov  edi,esi
552 diamond 134
    test cl,cl
135
    jns  .nextblock
51 mikedld 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
51 mikedld 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
51 mikedld 151
    add  edi,7
152
    jmp  .nextblock
153
  .no_gc:
552 diamond 154
end if
51 mikedld 155
    inc  edi
156
  .block_skip:
157
    movzx eax,byte[edi]
158
    lea  edi,[edi+eax+1]
552 diamond 159
    test eax,eax
51 mikedld 160
    jnz  .block_skip
161
    jmp  .nextblock
162
  .noextblock:
552 diamond 163
    mov  al,8
51 mikedld 164
    cmp  byte[edi],0x2c    ; image beginning
552 diamond 165
    jne  .ex
166
if defined gif_img_count
167
    inc  [gif_img_count]
168
end if
51 mikedld 169
    inc  edi
170
    mov  esi,[.cur_info]
552 diamond 171
if defined gif_img_count
51 mikedld 172
    add  esi,4
552 diamond 173
end if
51 mikedld 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
51 mikedld 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
51 mikedld 209
    push edi
552 diamond 210
    mov  ecx,[esi]
51 mikedld 211
    inc  esi
552 diamond 212
    test cl,cl
213
    js   .uselocal
51 mikedld 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)
51 mikedld 226
    pop  [.Palette]
552 diamond 227
end if
51 mikedld 228
    lea  esi,[edi+1]
552 diamond 229
    mov  edi,.gif_workarea
51 mikedld 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
51 mikedld 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
51 mikedld 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
51 mikedld 268
    mov  [.img_start],edi
552 diamond 269
    add  [.img_end],edi
270
    add  [.row_end],edi
271
end if
51 mikedld 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
51 mikedld 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
51 mikedld 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
51 mikedld 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
51 mikedld 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]
51 mikedld 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
51 mikedld 414
    end if
552 diamond 415
    end if
51 mikedld 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
 
51 mikedld 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