Subversion Repositories Kolibri OS

Rev

Rev 8341 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8341 dunkaist 1
;;================================================================================================;;
2
;;//// gif.asm //// (c) mike.dld, 2007-2008 //////////////////////////////////////////////////////;;
3
;;================================================================================================;;
4
;;//// Partial (c) by Willow, Diamond and HidnPlayr //////////////////////////////////////////////;;
5
;;================================================================================================;;
6
;;                                                                                                ;;
7
;; This file is part of Common development libraries (Libs-Dev).                                  ;;
8
;;                                                                                                ;;
9
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
10
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
11
;; of the License, or (at your option) any later version.                                         ;;
12
;;                                                                                                ;;
13
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
14
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
15
;; Lesser General Public License for more details.                                                ;;
16
;;                                                                                                ;;
17
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
18
;; If not, see .                                                    ;;
19
;;                                                                                                ;;
20
;;================================================================================================;;
21
;;                                                                                                ;;
22
;; References:                                                                                    ;;
23
;;   1. GIF LITE v3.0 (2004-2007)                                                                 ;;
24
;;      by Willow and Diamond                                                                     ;;
25
;;      svn://kolibrios.org/programs/media/gifview/trunk/gif_lite.inc                             ;;
26
;;   2. "GIF File Format Summary"                                                                 ;;
27
;;      from "Encyclopedia of Graphics File Formats" by O'Reilly                                  ;;
28
;;      http://www.fileformat.info/format/gif/                                                    ;;
29
;;   3. "LZW and GIF explained" (1987)                                                            ;;
30
;;      by Steve Blackstock, IEEE                                                                 ;;
31
;;      http://www.cis.udel.edu/~amer/CISC651/lzw.and.gif.explained.html                          ;;
32
;;   4. "Graphics Interchange Format (tm)" (June 15, 1987)                                        ;;
33
;;      by CompuServe Incorporated                                                                ;;
34
;;      http://examples.oreilly.de/english_examples/gff/CDROM/GFF/VENDSPEC/GIF/GIF87A.TXT         ;;
35
;;   5. "Graphics Interchange Format (sm)" (July 31, 1990)                                        ;;
36
;;      by CompuServe Incorporated                                                                ;;
37
;;      http://examples.oreilly.de/english_examples/gff/CDROM/GFF/VENDSPEC/GIF/GIF89A.TXT         ;;
38
;;                                                                                                ;;
39
;;================================================================================================;;
40
 
41
 
42
include 'gif.inc'
43
 
44
;;================================================================================================;;
45
proc img.is.gif _data, _length ;//////////////////////////////////////////////////////////////////;;
46
;;------------------------------------------------------------------------------------------------;;
47
;? Determine if raw data could be decoded (is in GIF format)                                      ;;
48
;;------------------------------------------------------------------------------------------------;;
49
;> _data = raw data as read from file/stream                                                      ;;
50
;> _length = data length                                                                          ;;
51
;;------------------------------------------------------------------------------------------------;;
52
;< eax = false / true                                                                             ;;
53
;;================================================================================================;;
54
	cmp	[_length], sizeof.gif.Header
55
	jb	.nope
56
	mov	eax, [_data]
57
	cmp	dword[eax], 'GIF8'
58
	jne	.nope
59
	cmp	word[eax + 4], '7a'
60
	je	.yep
61
	cmp	word[eax + 4], '9a'
62
	je	.yep
63
 
64
  .nope:
65
	xor	eax, eax
66
	ret
67
 
68
  .yep:
69
	xor	eax, eax
70
	inc	eax
71
	ret
72
endp
73
 
74
;;================================================================================================;;
75
proc img.decode.gif _data, _length, _options ;////////////////////////////////////////////////////;;
76
;;------------------------------------------------------------------------------------------------;;
77
;? Decode data into image if it contains correctly formed raw data in GIF format                  ;;
78
;;------------------------------------------------------------------------------------------------;;
79
;> _data = raw data as read from file/stream                                                      ;;
80
;> _length = data length                                                                          ;;
81
;;------------------------------------------------------------------------------------------------;;
82
;< eax = 0 (error) or pointer to image                                                            ;;
83
;;================================================================================================;;
84
locals
85
  max_color          dd ?
86
  cur_color_table_size dd ?
87
  transparent_color  dd ?
88
  background_color   dd ?
89
  options_bgr        dd ?
90
  prev_palette       dd ?
91
  aux_palette        dd ?
92
  img		     dd ?
93
  prev_img_data      dd ?
94
  aux_img_data       dd ?
95
  aux_img_type       dd ?
96
  prev_num_colors    dd ?
97
  main_img           dd ?
98
  global_color_table dd ?
99
  global_color_table_size dd ?
100
endl
101
 
102
img.decode.gif.main_img equ main_img
103
img.decode.gif.prev_img_data equ prev_img_data
104
img.decode.gif.transparent_color equ transparent_color
105
img.decode.gif.background_color equ background_color
106
img.decode.gif._length equ _length
107
img.decode.gif.prev_num_colors equ prev_num_colors
108
img.decode.gif.prev_palette equ prev_palette
109
img.decode.gif.max_color equ max_color
110
img.decode.gif._data equ _data
111
img.decode.gif.aux_img_data equ aux_img_data
112
img.decode.gif.aux_img_type equ aux_img_type
113
img.decode.gif.aux_palette equ aux_palette
114
img.decode.gif.options_bgr equ options_bgr
115
; offset of _length parameter for child functions with ebp-based frame
116
; child saved ebp, return address, 3 saved registers, 15 local variables
117
img.decode.gif._length_child equ _length + 4 + 4 + 4*3 + 4*15
118
img.decode.gif.max_color_child equ ebp + 4 + 4 + 4*3
119
img.decode.gif.cur_color_table_size_child equ ebp + 4 + 4 + 4*3 + 4
120
 
121
	push	ebx esi edi
122
	xor	eax, eax
123
	mov	[img], eax
124
	mov	[main_img], eax
125
	mov	[prev_img_data], eax
126
	mov	[aux_img_data], eax
127
	mov	[aux_img_type], eax
128
	mov	[prev_palette], eax
129
	mov	[aux_palette], eax
130
; when no previous image is available, use background fill with 1-entry palette
131
	inc	eax
132
	mov	[prev_num_colors], eax
133
	lea	eax, [background_color]
134
	mov	[prev_palette], eax
135
; value for bgr color in transparent images
136
	mov	edx, 0xFFFFFF	; white bgr if no value given
137
	mov	ecx, [_options]
138
	jecxz	@f
139
	cmp	[ecx + ImageDecodeOptions.UsedSize], ImageDecodeOptions.BackgroundColor + 4
140
	jb	@f
141
	mov	edx, [ecx + ImageDecodeOptions.BackgroundColor]
142
@@:
143
	mov	[options_bgr], edx
144
	mov	dword [eax], edx
145
; guard against incorrect gif files without any color tables
146
; "If no color table is available at
147
; all, the decoder is free to use a system color table or a table of its own. In
148
; that case, the decoder may use a color table with as many colors as its
149
; hardware is able to support; it is recommended that such a table have black and
150
; white as its first two entries, so that monochrome images can be rendered
151
; adequately." (c) official gif documentation
152
	mov	[global_color_table], gif_default_palette
153
	mov	[global_color_table_size], 2
154
 
155
; img.is.gif is called by caller (img.decode)
156
;	stdcall img.is.gif, [_data], [_length]
157
;	or	eax, eax
158
;	jz	.error
159
 
160
	mov	ebx, [_data]
161
	sub	[_length], sizeof.gif.Header
162
 
163
	mov	cl, [ebx + gif.Header.lsd.Packed]
164
	add	ebx, sizeof.gif.Header
165
; gif.LSD.Packed.GlobalColorTableFlag = 80h
166
;	test	cl, gif.LSD.Packed.GlobalColorTableFlag
167
;	jz	@f
168
	test	cl, cl
169
	jns	@f
170
	mov	[global_color_table], ebx
171
	and	cl, gif.LSD.Packed.SizeOfGlobalColorTableMask
172
;	shr	cl, gif.LSD.Packed.SizeOfGlobalColorTableShift	; here Shift = 0
173
	push	2
174
	pop	eax
175
	shl	eax, cl
176
	mov	[global_color_table_size], eax
177
	lea	eax, [eax * 3]
178
	sub	[_length], eax
179
	jbe	.error	; there must be at least 1 additional byte after color table
180
	movzx	ecx, byte [ebx - sizeof.gif.Header + gif.Header.lsd.BackgroundColor]
181
	lea	ecx, [ecx*3]
182
	mov	ecx, [ebx + ecx]	; eax = xxBBGGRR, convert to Kolibri color
183
	bswap	ecx
184
	shr	ecx, 8
185
	mov	[background_color], ecx
186
	add	ebx, eax
187
    @@:
188
 
189
;   @@: cmp     byte[ebx + gif.Block.Introducer], gif.Block.Introducer.Extension
190
;       jne     .next_image
191
;       cmp     byte[ebx + gif.Extension.Label], gif.Extension.Label.Comment
192
;       jne     .error
193
;       add     ebx, sizeof.gif.Extension
194
;       stdcall ._.skip_data
195
;       mov     ebx, eax
196
;       jmp     @b
197
 
198
  .next_image:
199
	stdcall img._.new
200
	or	eax, eax
201
	jz	.error
202
	mov	edx, [img]
203
	mov	[eax + Image.Previous], edx
204
	push	sizeof.gif.LogicalScreenDescriptor
205
	pop	ecx
206
	test	edx, edx
207
	jz	@f
208
	mov	[edx + Image.Next], eax
209
	xor	ecx, ecx
210
  @@:
211
	push	eax
212
	mov	[eax + Image.Type], Image.bpp8i
213
 
214
	add	ecx, sizeof.gif.Image
215
	invoke	mem.alloc, ecx
216
	pop	edx
217
	or	eax, eax
218
	jz	.error2
219
	mov	[edx + Image.Extended], eax
220
	xor	ecx, ecx
221
	cmp	[img], ecx
222
	jnz	@f
223
	mov	esi, [_data]
224
	add	esi, gif.Header.lsd
225
	lea	edi, [eax + sizeof.gif.Image]
226
	mov	cl, sizeof.gif.LogicalScreenDescriptor
227
	rep	movsb
228
	mov	[main_img], edx
229
  @@:
230
	mov	[img], edx
231
 
232
	stdcall ._.process_extensions
233
 
234
	cmp	al, gif.Block.Introducer.ImageDescriptor
235
	jne	.error
236
	sub	[_length], sizeof.gif.ImageDescriptor
237
	jc	.error
238
	movzx	eax, [ebx + gif.ImageDescriptor.Width]
239
	movzx	ecx, [ebx + gif.ImageDescriptor.Height]
240
	push	edx
241
	stdcall img._.resize_data, [img], eax, ecx
242
	pop	edx
243
	or	eax, eax
244
	jz	.error
245
 
246
	mov	esi, ebx
247
	mov	edi, [edx + Image.Extended]
248
	mov	ecx, sizeof.gif.ImageDescriptor
249
	rep	movsb
250
 
251
	mov	edi, [edx + Image.Palette]
252
	mov	esi, [global_color_table]
253
	mov	ecx, [global_color_table_size]
254
	test	[ebx + gif.ImageDescriptor.Packed], gif.ID.Packed.LocalColorTableFlag
255
	jz	@f
256
	lea	esi, [ebx + sizeof.gif.ImageDescriptor]
257
	mov	cl, [ebx + gif.ImageDescriptor.Packed]
258
	and	cl, gif.ID.Packed.SizeOfLocalColorTableMask
259
; here Shift = 0
260
;	shr	cl, gif.ID.Packed.SizeOfLocalColorTableShift
261
	push	2
262
	pop	eax
263
	shl	eax, cl
264
	mov	ecx, eax
265
	lea	eax, [eax*3]
266
	add	ebx, eax
267
	sub	[_length], eax
268
	jbe	.error	; because we load additional byte, check is 'jbe', not 'jc'
269
@@:
270
	mov	[cur_color_table_size], ecx
271
	dec	[cur_color_table_size]
272
@@:
273
	lodsd
274
	dec	esi
275
	bswap	eax
8394 dunkaist 276
	mov	al, 0xff        ; opaque
277
	ror	eax, 8
8341 dunkaist 278
	stosd
279
	loop	@b
280
	add	ebx, sizeof.gif.ImageDescriptor
281
	stdcall ._.process_image
282
	push	ebx
283
	mov	edx, [img]
284
	push	edx
285
	stdcall	._.superimpose
286
	pop	edx
287
	push	edx
288
	stdcall	._.dispose
289
	pop	edx
290
	mov	edx, [edx + Image.Previous]
291
	test	edx, edx
292
	jz	.nofreeprev
293
	mov	ebx, [edx + Image.Extended]
294
	cmp	[edx + Image.Delay], 0
295
	jnz	.nofreeprev
296
	mov	esi, [prev_palette]
297
	cmp	esi, [edx + Image.Palette]
298
	jnz	@f
299
	mov	ecx, [prev_num_colors]
300
	stdcall	._.alloc_aux_palette
301
	test	eax, eax
302
	jz	.nofreeprev
303
	mov	[prev_palette], eax
304
    @@:
305
	mov	esi, [prev_img_data]
306
	cmp	esi, [edx + Image.Data]
307
	jnz	.noprevdata
308
	push	1
309
	pop	eax
310
	cmp	[edx + Image.Type], Image.bpp8i
311
	jz	@f
312
	mov	al, 3
313
    @@:
314
	cmp	[aux_img_type], eax
315
	jb	.resetaux
316
	mov	edi, [aux_img_data]
317
	imul	eax, [edx + Image.Width]
318
	imul	eax, [edx + Image.Height]
319
	xchg	eax, ecx
320
	rep	movsb
321
	jmp	.noprevdata
322
    .resetaux:
323
	mov	[aux_img_type], eax
324
	mov	eax, [aux_img_data]
325
	test	eax, eax
326
	jz	@f
327
	invoke	mem.free, eax
328
    @@:
329
	xor	eax, eax
330
	xchg	eax, [edx + Image.Data]
331
	mov	[aux_img_data], eax
332
    .noprevdata:
333
	cmp	edx, [main_img]
334
	jnz	@f
335
	mov	eax, [edx + Image.Next]
336
	mov	[main_img], eax
337
	mov	esi, [eax + Image.Extended]
338
	mov	edi, [edx + Image.Extended]
339
	mov	[edx + Image.Extended], esi
340
	mov	[eax + Image.Extended], edi
341
	push	sizeof.gif.Image
342
	pop	ecx
343
	rep	movsb
344
    @@:
345
	stdcall	img.destroy.layer, edx
346
  .nofreeprev:
347
	pop	ebx
348
	test	ebx, ebx
349
	jz	.ret
350
	jmp	.next_image
351
 
352
  .error2:
353
	mov	[img], edx
354
 
355
  .error:
356
	mov	eax, [img]
357
	test	eax, eax
358
	jz	.ret
359
	cmp	[main_img], eax
360
	jnz	@f
361
	and	[main_img], 0
362
  @@:
363
	stdcall	img.destroy.layer, eax
364
  .ret:
365
	mov	eax, [aux_img_data]
366
	test	eax, eax
367
	jz	@f
368
	invoke	mem.free, eax
369
  @@:
370
	mov	eax, [aux_palette]
371
	test	eax, eax
372
	jz	@f
373
	invoke	mem.free, eax
374
  @@:
375
	mov	eax, [main_img]
376
	cmp	[eax + Image.Next], 0
377
	jz	@f
378
	or	[eax + Image.Flags], Image.IsAnimated
379
  @@:
380
	pop	edi esi ebx
381
	ret
382
endp
383
 
384
;;================================================================================================;;
385
proc img.encode.gif _img, _p_length ;/////////////////////////////////////////////////////////////;;
386
;;------------------------------------------------------------------------------------------------;;
387
;? Encode image into raw data in GIF format                                                       ;;
388
;;------------------------------------------------------------------------------------------------;;
389
;> _img = pointer to image                                                                        ;;
390
;;------------------------------------------------------------------------------------------------;;
391
;< eax = 0 (error) or pointer to encoded data                                                     ;;
392
;< _p_length = encoded data length                                                                ;;
393
;;================================================================================================;;
394
	xor	eax, eax
395
	ret
396
endp
397
 
398
 
399
;;================================================================================================;;
400
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
401
;;================================================================================================;;
402
;! Below are private procs you should never call directly from your code                          ;;
403
;;================================================================================================;;
404
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
405
;;================================================================================================;;
406
 
407
 
408
;;================================================================================================;;
409
proc img.decode.gif._.process_extensions ;////////////////////////////////////////////////////////;;
410
;;------------------------------------------------------------------------------------------------;;
411
;? --- TBD ---                                                                                    ;;
412
;;------------------------------------------------------------------------------------------------;;
413
;> ebx = raw image data                                                                           ;;
414
;> edx = image data                                                                               ;;
415
;;------------------------------------------------------------------------------------------------;;
416
;< --- TBD ---                                                                                    ;;
417
;;================================================================================================;;
418
	mov	esi, ebx
419
	xor	eax, eax
420
	mov	[edx + Image.Delay], eax
421
 
422
  .next_block:
423
	dec	[img.decode.gif._length]
424
	js	.exit_err
425
	lodsb	; load gif.Block.Introducer
426
	cmp	al, gif.Block.Introducer.Extension
427
	jne	.exit
428
 
429
  .ext_block:
430
	dec	[img.decode.gif._length]
431
	js	.exit_err
432
	lodsb	; load gif.Extension.Label
433
	cmp	al, gif.Extension.Label.GraphicsControl
434
	je	.graphics_control_ext
435
;	cmp	al, gif.Extension.Label.PlainText
436
;	je	.plain_text_ext
437
;	cmp	al, gif.Extension.Label.Comment
438
;	je	.comment_ext
439
;	cmp	al, gif.Extension.Label.Application
440
;	je	.application_ext
441
; skip all other extensions
442
  .skip_ext:
443
	dec	[img.decode.gif._length]
444
	js	.exit_err
445
	lodsb	; load BlockSize
446
  .1:
447
	test	al, al
448
	jz	.next_block
449
	sub	[img.decode.gif._length], eax
450
	jc	.exit_err
451
	add	esi, eax
452
	jmp	.skip_ext
453
 
454
  .graphics_control_ext:
455
	dec	[img.decode.gif._length]
456
	js	.exit_err
457
	lodsb	; load BlockSize; must be sizeof.gif.GraphicsControlExtension
458
	cmp	al, sizeof.gif.GraphicsControlExtension
459
	jnz	.1
460
	sub	[img.decode.gif._length], eax
461
	jc	.exit_err
462
	push	edi
463
	movzx	edi, [esi + gif.GraphicsControlExtension.DelayTime]
464
	mov	[edx + Image.Delay], edi
465
	mov	edi, [edx + Image.Extended]
466
	add	edi, gif.Image.gce
467
	mov	ecx, eax
468
	rep	movsb
469
	pop	edi
470
	jmp	.skip_ext
471
 
472
  .exit_err:
473
	xor	eax, eax
474
 
475
  .exit:
476
	mov	ebx, esi
477
	ret
478
endp
479
 
480
;;================================================================================================;;
481
proc img.decode.gif._.process_image ;/////////////////////////////////////////////////////////////;;
482
;;------------------------------------------------------------------------------------------------;;
483
;? --- TBD ---                                                                                    ;;
484
;;------------------------------------------------------------------------------------------------;;
485
;> ebx = raw image data                                                                           ;;
486
;> edx = image data                                                                               ;;
487
;;------------------------------------------------------------------------------------------------;;
488
;< --- TBD ---                                                                                    ;;
489
;;================================================================================================;;
490
locals
491
  width      dd ?
492
  img_start  dd ?
493
  img_end    dd ?
494
  row_end    dd ?
495
  pass	     dd ?
496
  codesize   dd ?
497
  compsize   dd ?
498
  workarea   dd ?
499
  block_ofs  dd ?
500
  bit_count  dd ?
501
  CC	     dd ?
502
  EOI	     dd ?
503
endl
504
 
505
	invoke	mem.alloc, 16 * 1024
506
	mov	[workarea], eax
507
	or	eax, eax
508
	jz	.error
509
 
510
	mov	ecx, [edx + Image.Width]
511
	mov	[width], ecx
512
	mov	eax, [edx + Image.Height]
513
	imul	eax, ecx
514
	mov	[img_end], eax
515
	inc	eax
516
	mov	[row_end], eax
517
	and	[pass], 0
518
	and	dword [img.decode.gif.max_color_child], 0
519
	mov	eax, [edx + Image.Extended]
520
	test	[eax + gif.Image.info.Packed], gif.ID.Packed.InterleaceFlag
521
	jz	@f
522
	mov	[row_end], ecx
523
 
524
    @@: mov	esi, ebx
525
	mov	edi, [edx + Image.Data]
526
 
527
	sub	dword [img.decode.gif._length_child], 2
528
	jc	.error
529
	movzx	ecx, byte[esi]
530
	inc	esi
531
	cmp	cl, 12
532
	jae	.error
533
	mov	[codesize], ecx
534
	inc	[codesize]
535
	xor	eax, eax
536
	lodsb				; eax - block_count
537
	sub	[img.decode.gif._length_child], eax
538
	jc	.error
539
	add	eax, esi
540
	push	edi
541
	mov	edi, [workarea]
542
	mov	[block_ofs], eax
543
	mov	[bit_count], 8
544
	mov	eax, 1
545
	shl	eax, cl
546
	mov	[CC], eax
547
	mov	ecx, eax
548
	inc	eax
549
	mov	[EOI], eax
550
	mov	eax, gif.Null shl 16
551
  .filltable:
552
	stosd
553
	inc	eax
554
	loop	.filltable
555
	pop	edi
556
	mov	[img_start], edi
557
	add	[img_end], edi
558
	add	[row_end], edi
559
  .reinit:
560
	mov	edx, [EOI]
561
	inc	edx
562
	push	[codesize]
563
	pop	[compsize]
564
	call	.get_symbol
565
	cmp	eax, [CC]
566
	je	.reinit
567
	call	.output
568
  .cycle:
569
	movzx	ebx, ax
570
	call	.get_symbol
571
	cmp	eax, [EOI]
572
	je	.end
573
	cmp	eax, edx
574
	ja	.error
575
	je	.notintable
576
	cmp	eax, [CC]
577
	je	.reinit
578
	call	.output
579
  .add:
580
	cmp	edx, 0x00001000
581
	jae	.cycle
582
	mov	ecx, [workarea]
583
	mov	[ecx + edx * 4], ebx
584
	inc	edx
585
	cmp	edx, 0x1000
586
	je	.noinc
587
	bsr	ebx, edx
588
	cmp	ebx, [compsize]
589
	jne	.noinc
590
	inc	[compsize]
591
  .noinc:
592
	jmp	.cycle
593
  .notintable:
594
	push	eax
595
	mov	eax, ebx
596
	call	.output
597
	push	ebx
598
	movzx	eax, bx
599
	call	.output
600
	pop	ebx eax
601
	jmp	.add
602
  .end:
603
	mov	edi, [img_end]
604
	xor	eax, eax
605
 
606
  .exit:
607
	cmp	[workarea], 0
608
	je	@f
609
	invoke	mem.free, [workarea]
610
    @@:
611
	mov	ebx, [block_ofs]
612
    @@:
613
	dec	[img.decode.gif._length_child]
614
	js	@f
615
	movzx	eax, byte [ebx]
616
	inc	ebx
617
	test	eax, eax
618
	jz	.ret
619
	sub	[img.decode.gif._length_child], eax
620
	jc	@f
621
	add	ebx, eax
622
	jmp	@b
623
 
624
  .error:
625
	cmp	[workarea], 0
626
	je	@f
627
	invoke	mem.free, [workarea]
628
    @@: xor	ebx, ebx
629
  .ret:
630
	ret
631
 
632
;;------------------------------------------------------------------------------------------------;;
633
 
634
img.decode.gif._.process_image.get_symbol:
635
	mov	ecx, [compsize]
636
	push	ecx
637
	xor	eax, eax
638
 
639
  .shift:
640
	dec	[bit_count]
641
	jns	.loop1
642
	inc	esi
643
	cmp	esi, [block_ofs]
644
	jb	.noblock
645
	push	eax
646
	xor	eax, eax
647
	sub	[img.decode.gif._length_child], 1
648
	jc	.error_eof
649
	lodsb
650
	test	eax, eax
651
	jnz	.nextbl
652
  .error_eof:
653
	add	esp, 12
654
	jmp	img.decode.gif._.process_image.error
655
 
656
  .nextbl:
657
	sub	[img.decode.gif._length_child], eax
658
	jc	.error_eof
659
	add	eax, esi
660
	mov	[block_ofs], eax
661
	pop	eax
662
 
663
  .noblock:
664
	mov	[bit_count], 7
665
 
666
  .loop1:
667
	ror	byte[esi], 1
668
	rcr	eax,1
669
	loop	.shift
670
	pop	ecx
671
	rol	eax, cl
672
 
673
  .exit:
674
	xor	ecx, ecx
675
	retn
676
 
677
;;------------------------------------------------------------------------------------------------;;
678
 
679
img.decode.gif._.process_image.output:
680
	push	esi eax edx
681
	mov	edx, [workarea]
682
 
683
  .next:
684
	pushw	[edx + eax * 4]
685
	mov	ax, [edx + eax * 4 + 2]
686
	inc	ecx
687
	cmp	ax, gif.Null
688
	jnz	.next
689
	shl	ebx, 16
690
	mov	bx, [esp]
691
 
692
  .loop2:
693
	pop	ax
694
	cmp	al, byte [img.decode.gif.cur_color_table_size_child]
695
	jbe	@f	; guard against incorrect GIFs
696
	mov	al, 0
697
    @@: cmp	al, byte [img.decode.gif.max_color_child]
698
	jbe	@f
699
	mov	[img.decode.gif.max_color_child], al
700
    @@:	stosb
701
 
702
	cmp	edi, [row_end]
703
	jb	.norowend
704
	mov	eax, [width]
705
	push	eax
706
	sub	edi, eax
707
	add	eax, eax
708
	cmp	[pass], 3
709
	je	@f
710
	add	eax, eax
711
	cmp	[pass], 2
712
	je	@f
713
	add	eax, eax
714
    @@: add	edi, eax
715
	pop	eax
716
	cmp	edi, [img_end]
717
	jb	.nextrow
718
	mov	edi, [img_start]
719
	inc	[pass]
720
	cmp	[pass], 4
721
	je	.done
722
	add	edi, eax
723
	cmp	[pass], 3
724
	je	@f
725
	add	edi, eax
726
	cmp	[pass], 2
727
	je	@f
728
	add	edi, eax
729
	add	edi, eax
730
    @@:
731
 
732
  .nextrow:
733
	add	eax, edi
734
	mov	[row_end], eax
735
	xor	eax, eax
736
 
737
  .norowend:
738
	cmp	edi, [img_end]
739
	jz	.done
740
	loop	.loop2
741
	pop	edx eax esi
742
	retn
743
 
744
  .done:
745
	lea	esp, [esp+(ecx-1)*2]
746
	pop	edx eax esi eax
747
	jmp	img.decode.gif._.process_image.exit
748
 
749
endp
750
 
751
;;================================================================================================;;
752
proc img.decode.gif._.is_logical_screen ;/////////////////////////////////////////////////////////;;
753
;;------------------------------------------------------------------------------------------------;;
754
;? Determines whether GIF image occupies the whole logical screen                                 ;;
755
;;------------------------------------------------------------------------------------------------;;
756
;> eax = extended image data                                                                      ;;
757
;> ebx = main image                                                                               ;;
758
;;------------------------------------------------------------------------------------------------;;
759
;< ZF set <=> image area equals logical screen                                                    ;;
760
;;================================================================================================;;
761
	mov	ebx, [ebx + Image.Extended]
762
	cmp	[eax + gif.Image.info.Left], 0
763
	jnz	@f
764
	cmp	[eax + gif.Image.info.Top], 0
765
	jnz	@f
766
	mov	cx, [eax + gif.Image.info.Width]
767
	cmp	cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
768
	jnz	@f
769
	mov	cx, [eax + gif.Image.info.Height]
770
	cmp	cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
771
@@:	retn
772
endp
773
 
774
main_img equ img.decode.gif.main_img
775
transparent_color equ img.decode.gif.transparent_color
776
background_color equ img.decode.gif.background_color
777
prev_num_colors equ img.decode.gif.prev_num_colors
778
prev_palette equ img.decode.gif.prev_palette
779
max_color equ img.decode.gif.max_color
780
prev_img_data equ img.decode.gif.prev_img_data
781
_data equ img.decode.gif._data
782
aux_img_data equ img.decode.gif.aux_img_data
783
aux_img_type equ img.decode.gif.aux_img_type
784
aux_palette equ img.decode.gif.aux_palette
785
 
786
;;================================================================================================;;
787
proc img.decode.gif._.superimpose ;///////////////////////////////////////////////////////////////;;
788
;;------------------------------------------------------------------------------------------------;;
789
;? --- TBD ---                                                                                    ;;
790
;;------------------------------------------------------------------------------------------------;;
791
;> edx = image data                                                                               ;;
792
;;------------------------------------------------------------------------------------------------;;
793
;< --- TBD ---                                                                                    ;;
794
;;================================================================================================;;
795
	mov	ebx, [main_img]
796
	mov	eax, [edx + Image.Extended]
797
	or	[transparent_color], -1		; no transparent color
798
	test	byte [eax + gif.Image.gce.Packed], 1
799
	jz	@f
800
	movzx	ecx, byte [eax + gif.Image.gce.ColorIndex]
801
	mov	[transparent_color], ecx
802
	cmp	edx, ebx
803
	jnz	.has_transparency
804
	shl	ecx, 2
805
	add	ecx, [edx + Image.Palette]
806
	push	eax
807
	mov	eax, [img.decode.gif.options_bgr]
808
	mov	dword [background_color], eax
809
	mov	dword [ecx], eax
810
	pop	eax
811
@@:
812
	call	img.decode.gif._.is_logical_screen
813
	jnz	.has_transparency
814
; image is not transparent, so keep it as is
815
	retn
816
 
817
.has_transparency:
818
; image has transparent areas, we must superimpose it on the previous
819
	mov	ecx, [prev_num_colors]
820
	cmp	ecx, 0x100
821
	ja	.superimpose_on_rgb
822
; create common palette
823
	sub	esp, 3FCh
824
	push	eax
825
	mov	edi, esp
826
	push	ecx
827
	mov	esi, [prev_palette]
828
	rep	movsd
829
	pop	ecx
830
	mov	esi, [edx + Image.Palette]
831
	xor	ebx, ebx
832
	mov	edi, esp
833
	sub	esp, 100h
834
.create_palette_loop:
835
	push	ecx
836
	lodsd
837
	cmp	ebx, [transparent_color]
838
	jz	.nochange
839
	cmp	ebx, ecx
840
	jae	@f
841
	cmp	eax, [edi+ebx*4]
842
	jz	.nochange
843
@@:
844
	push	edi
845
	repnz	scasd
846
	pop	edi
847
	jnz	.increase_palette
848
	sub	ecx, [esp]
849
	not	ecx	; cl = index of new color in current palette
850
	jmp	.palette_common
851
.increase_palette:
852
	mov	ecx, [esp]
853
	test	ch, ch
854
	jnz	.output_to_rgb
855
	inc	dword [esp]
856
	mov	[edi+ecx*4], eax
857
	jmp	.palette_common
858
.nochange:
859
	mov	ecx, ebx
860
.palette_common:
861
	mov	[ebx+esp+4], cl
862
	pop	ecx
863
	inc	ebx
864
	cmp	ebx, [max_color]
865
	jbe	.create_palette_loop
866
	mov	[max_color], ecx
867
; if image occupies only part of logical screen, allocate memory for full logical screen
868
	mov	ebx, [main_img]
869
	mov	eax, [edx + Image.Extended]
870
	mov	esi, [edx + Image.Data]
871
	call	img.decode.gif._.is_logical_screen
872
	jz	@f
873
	and	[edx + Image.Data], 0
874
	push	edx
875
	movzx	eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
876
	push	eax
877
	movzx	eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
878
	stdcall	img._.resize_data, edx, eax
879
	pop	edx
880
	test	eax, eax
881
	jz	.palette_nomem
882
@@:
883
; copy final palette to Image.Palette
884
	push	esi esi
885
	mov	esi, edi
886
	mov	edi, [edx + Image.Palette]
887
	mov	ecx, [max_color]
888
	dec	[max_color]
889
	rep	movsd
890
	mov	esi, [prev_img_data]
891
	mov	edi, [edx + Image.Data]
892
; do superimpose, [esp] -> source data, esi -> prev image data
893
;   (NULL if previous image is filled with background color), esp+8 -> correspondence between
894
;   used palette and final palette, edi -> destination data
895
	mov	ebx, [edx + Image.Extended]
896
; first Top rows are copied from [prev_img_data] or filled with bgr
897
	movzx	ecx, [ebx + gif.Image.info.Top]
898
	cmp	ecx, [edx + Image.Height]
899
	jb	@f
900
	mov	ecx, [edx + Image.Height]
901
@@:
902
	push	ecx
903
	imul	ecx, [edx + Image.Width]
904
	call	.rep_movsb_or_stosb
905
	pop	ecx
906
; convert rows
907
	sub	ecx, [edx + Image.Height]
908
	neg	ecx
909
	push	ecx
910
	cmp	cx, [ebx + gif.Image.info.Height]
911
	jbe	@f
912
	mov	cx, [ebx + gif.Image.info.Height]
913
@@:
914
	jecxz	.norows
915
.convert_rows:
916
	push	ecx
917
	movzx	ecx, [ebx + gif.Image.info.Left]
918
	cmp	ecx, [edx + Image.Width]
919
	jb	@f
920
	mov	ecx, [edx + Image.Width]
921
@@:
922
	push	ecx
923
	call	.rep_movsb_or_stosb
924
	pop	ecx
925
	sub	ecx, [edx + Image.Width]
926
	neg	ecx
927
	push	ecx edx
928
	mov	edx, [esp+16]	; source data
929
	cmp	cx, [ebx + gif.Image.info.Width]
930
	jbe	@f
931
	mov	cx, [ebx + gif.Image.info.Width]
932
@@:
933
	jecxz	.norowsi
934
.rowsloop:
935
	movzx	eax, byte [edx]
936
	inc	edx
937
	cmp	eax, [transparent_color]
938
	jz	.rows_transparent
939
	mov	al, [eax+esp+24]
940
	stosb
941
	call	.lodsb
942
	jmp	@f
943
.rows_transparent:
944
	call	.lodsb
945
	stosb
946
@@:
947
	loop	.rowsloop
948
.norowsi:
949
	pop	edx ecx
950
	sub	cx, [ebx + gif.Image.info.Width]
951
	jbe	@f
952
	call	.rep_movsb_or_stosb
953
@@:
954
	movzx	eax, [ebx + gif.Image.info.Width]
955
	add	[esp+8], eax
956
	pop	ecx
957
	loop	.convert_rows
958
.norows:
959
	pop	ecx
960
	sub	cx, [ebx + gif.Image.info.Height]
961
	jbe	@f
962
	imul	ecx, [edx + Image.Width]
963
	call	.rep_movsb_or_stosb
964
@@:
965
; free old image data if we have allocated new copy
966
	pop	esi esi
967
	cmp	esi, [edx + Image.Data]
968
	jz	@f
969
	invoke	mem.free, esi
970
@@:
971
; cleanup stack and return
972
	add	esp, 500h
973
	retn
974
.palette_nomem:
975
	mov	[edx + Image.Data], esi
976
	jmp	@b
977
 
978
.output_to_rgb:
979
	pop	ecx
980
	add	esp, 500h
981
; compose two palette-based images to one RGB image
982
	xor	esi, esi
983
	xchg	esi, [edx + Image.Data]
984
	push	esi
985
	mov	ebx, [_data]
986
	push	[edx + Image.Palette]
987
	mov	byte [edx + Image.Type], Image.bpp24
988
	push	edx
989
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
990
	push	eax
991
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
992
	stdcall	img._.resize_data, edx, eax
993
	pop	edx
994
	test	eax, eax
995
	jz	.convrgb_nomem
996
	push	esi
997
	mov	edi, [edx + Image.Data]
998
	mov	esi, [prev_img_data]
999
	mov	ebx, [edx + Image.Extended]
1000
; first Top rows are copied from [prev_img_data] or filled with bgr
1001
	movzx	ecx, [ebx + gif.Image.info.Top]
1002
	cmp	ecx, [edx + Image.Height]
1003
	jb	@f
1004
	mov	ecx, [edx + Image.Height]
1005
@@:
1006
	push	ecx
1007
	imul	ecx, [edx + Image.Width]
1008
	call	.convrgb_prev
1009
	pop	ecx
1010
; convert rows
1011
	sub	ecx, [edx + Image.Height]
1012
	neg	ecx
1013
	push	ecx
1014
	cmp	cx, [ebx + gif.Image.info.Height]
1015
	jbe	@f
1016
	mov	cx, [ebx + gif.Image.info.Height]
1017
@@:
1018
	jecxz	.convrgb_norows
1019
.convrgb_convert_rows:
1020
	push	ecx
1021
	movzx	ecx, [ebx + gif.Image.info.Left]
1022
	cmp	ecx, [edx + Image.Width]
1023
	jb	@f
1024
	mov	ecx, [edx + Image.Width]
1025
@@:
1026
	push	ecx
1027
	call	.convrgb_prev
1028
	pop	ecx
1029
	sub	ecx, [edx + Image.Width]
1030
	neg	ecx
1031
	push	ecx edx
1032
	mov	edx, [esp+16]	; source data
1033
	cmp	cx, [ebx + gif.Image.info.Width]
1034
	jbe	@f
1035
	mov	cx, [ebx + gif.Image.info.Width]
1036
@@:
1037
	jecxz	.convrgb_norowsi
1038
.convrgb_rowsloop:
1039
	movzx	eax, byte [edx]
1040
	inc	edx
1041
	cmp	eax, [transparent_color]
1042
	jz	.convrgb_rows_transparent
1043
	shl	eax, 2
1044
	add	eax, [esp+20]	; source palette
1045
	mov	eax, [eax]
1046
	stosw
1047
	shr	eax, 16
1048
	stosb
1049
	call	.convrgb_lodsb
1050
	jmp	@f
1051
.convrgb_rows_transparent:
1052
	call	.convrgb_lodsb
1053
	stosw
1054
	shr	eax, 16
1055
	stosb
1056
@@:
1057
	loop	.convrgb_rowsloop
1058
.convrgb_norowsi:
1059
	pop	edx ecx
1060
	sub	cx, [ebx + gif.Image.info.Width]
1061
	jbe	@f
1062
	call	.convrgb_prev
1063
@@:
1064
	movzx	eax, [ebx + gif.Image.info.Width]
1065
	add	[esp+8], eax
1066
	pop	ecx
1067
	loop	.convrgb_convert_rows
1068
.convrgb_norows:
1069
	pop	ecx
1070
	sub	cx, [ebx + gif.Image.info.Height]
1071
	jbe	@f
1072
	imul	ecx, [edx + Image.Width]
1073
	call	.convrgb_prev
1074
@@:
1075
; free old image data
1076
	pop	esi esi ;esi
1077
	invoke	mem.free;, esi
1078
	retn
1079
.convrgb_nomem:
1080
	pop	esi esi
1081
	retn
1082
 
1083
.superimpose_on_rgb:
1084
; previous image is RGB, new image has transparent areas
1085
	xor	esi, esi
1086
	xchg	esi, [edx + Image.Data]
1087
	push	esi
1088
	mov	ebx, [_data]
1089
	push	[edx + Image.Palette]
1090
	mov	byte [edx + Image.Type], Image.bpp24
1091
	push	edx
1092
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1093
	push	eax
1094
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1095
	stdcall	img._.resize_data, edx, eax
1096
	pop	edx
1097
	test	eax, eax
1098
	jz	.rgb_nomem
1099
	push	esi
1100
	mov	edi, [edx + Image.Data]
1101
	mov	esi, [prev_img_data]
1102
	mov	ebx, [edx + Image.Extended]
1103
; first Top rows are copied from [prev_img_data] or filled with bgr
1104
	movzx	ecx, [ebx + gif.Image.info.Top]
1105
	cmp	ecx, [edx + Image.Height]
1106
	jb	@f
1107
	mov	ecx, [edx + Image.Height]
1108
@@:
1109
	push	ecx
1110
	lea	ecx, [ecx*3]
1111
	imul	ecx, [edx + Image.Width]
1112
	rep	movsb
1113
	pop	ecx
1114
; convert rows
1115
	sub	ecx, [edx + Image.Height]
1116
	neg	ecx
1117
	push	ecx
1118
	cmp	cx, [ebx + gif.Image.info.Height]
1119
	jbe	@f
1120
	mov	cx, [ebx + gif.Image.info.Height]
1121
@@:
1122
	jecxz	.rgb_norows
1123
.rgb_convert_rows:
1124
	push	ecx
1125
	movzx	ecx, [ebx + gif.Image.info.Left]
1126
	cmp	ecx, [edx + Image.Width]
1127
	jb	@f
1128
	mov	ecx, [edx + Image.Width]
1129
@@:
1130
	push	ecx
1131
	lea	ecx, [ecx*3]
1132
	rep	movsb
1133
	pop	ecx
1134
	sub	ecx, [edx + Image.Width]
1135
	neg	ecx
1136
	push	ecx edx
1137
	mov	edx, [esp+16]	; source data
1138
	cmp	cx, [ebx + gif.Image.info.Width]
1139
	jbe	@f
1140
	mov	cx, [ebx + gif.Image.info.Width]
1141
@@:
1142
	jecxz	.rgb_norowsi
1143
.rgb_rowsloop:
1144
	movzx	eax, byte [edx]
1145
	inc	edx
1146
	cmp	eax, [transparent_color]
1147
	jz	.rgb_rows_transparent
1148
	shl	eax, 2
1149
	add	eax, [esp+20]	; source palette
1150
	mov	eax, [eax]
1151
	stosw
1152
	shr	eax, 16
1153
	stosb
1154
	add	esi, 3
1155
	jmp	@f
1156
.rgb_rows_transparent:
1157
	movsb
1158
	movsb
1159
	movsb
1160
@@:
1161
	loop	.rgb_rowsloop
1162
.rgb_norowsi:
1163
	pop	edx ecx
1164
	sub	cx, [ebx + gif.Image.info.Width]
1165
	jbe	@f
1166
	lea	ecx, [ecx*3]
1167
	rep	movsb
1168
@@:
1169
	movzx	eax, [ebx + gif.Image.info.Width]
1170
	add	[esp+8], eax
1171
	pop	ecx
1172
	loop	.rgb_convert_rows
1173
.rgb_norows:
1174
	pop	ecx
1175
	sub	cx, [ebx + gif.Image.info.Height]
1176
	jbe	@f
1177
	imul	ecx, [edx + Image.Width]
1178
	lea	ecx, [ecx*3]
1179
	rep	movsb
1180
@@:
1181
; free old image data
1182
	pop	esi esi ;esi
1183
	invoke	mem.free;, esi
1184
	retn
1185
.rgb_nomem:
1186
	pop	esi esi
1187
	retn
1188
 
1189
.lodsb:
1190
	xor	eax, eax
1191
	test	esi, esi
1192
	jz	@f
1193
	lodsb
1194
@@:	retn
1195
 
1196
.rep_movsb_or_stosb:
1197
	test	esi, esi
1198
	jz	.rmos1
1199
	rep	movsb
1200
	jmp	.rmos2
1201
.rmos1:	xor	eax, eax	; background index in final palette is 0 in bgr mode
1202
	rep	stosb
1203
.rmos2:	retn
1204
 
1205
.convrgb_prev:
1206
	jecxz	.convrgb_noprev
1207
	test	esi, esi
1208
	jz	.convrgb_prev_bgr
1209
@@:
1210
	xor	eax, eax
1211
	lodsb
1212
	shl	eax, 2
1213
	add	eax, [prev_palette]
1214
	mov	eax, [eax]
1215
	stosw
1216
	shr	eax, 16
1217
	stosb
1218
	loop	@b
1219
	retn
1220
.convrgb_prev_bgr:
1221
@@:
1222
	mov	eax, [background_color]
1223
	stosw
1224
	shr	eax, 16
1225
	stosb
1226
	loop	@b
1227
.convrgb_noprev:
1228
	retn
1229
.convrgb_lodsb:
1230
	xor	eax, eax
1231
	test	esi, esi
1232
	jz	@f
1233
	lodsb
1234
	shl	eax, 2
1235
	add	eax, [prev_palette]
1236
	mov	eax, [eax]
1237
	retn
1238
@@:	mov	eax, [background_color]
1239
	retn
1240
 
1241
endp
1242
 
1243
;;================================================================================================;;
1244
proc img.decode.gif._.dispose ;///////////////////////////////////////////////////////////////////;;
1245
;;------------------------------------------------------------------------------------------------;;
1246
;? --- TBD ---                                                                                    ;;
1247
;;------------------------------------------------------------------------------------------------;;
1248
;> edx = image data                                                                               ;;
1249
;;------------------------------------------------------------------------------------------------;;
1250
;< --- TBD ---                                                                                    ;;
1251
;;================================================================================================;;
1252
	mov	ebx, [edx + Image.Extended]
1253
	mov	al, [ebx + gif.Image.gce.Packed]
1254
	shr	al, 2
1255
	and	al, 7
1256
	cmp	al, 2
1257
	jz	.background
1258
	cmp	al, 3
1259
	jz	.previous
1260
; don't dispose - set prev_img and related vars to current image
1261
	mov	eax, [edx + Image.Data]
1262
	mov	[prev_img_data], eax
1263
	cmp	[edx + Image.Type], Image.bpp8i
1264
	jnz	@f
1265
	mov	eax, [max_color]
1266
	inc	eax
1267
	mov	[prev_num_colors], eax
1268
	mov	eax, [edx + Image.Palette]
1269
	mov	[prev_palette], eax
1270
	retn
1271
@@:
1272
	or	[prev_num_colors], -1
1273
	and	[prev_palette], 0
1274
.previous:
1275
	retn
1276
.background:
1277
	cmp	[prev_img_data], 0
1278
	jz	.bgr_full
1279
	mov	ebx, [main_img]
1280
	mov	eax, [edx + Image.Extended]
1281
	call	img.decode.gif._.is_logical_screen
1282
	jnz	@f
1283
.bgr_full:
1284
	xor	eax, eax
1285
	mov	[prev_img_data], eax
1286
	inc	eax
1287
	mov	[prev_num_colors], eax
1288
	lea	eax, [background_color]
1289
	mov	[prev_palette], eax
1290
	retn
1291
@@:
1292
	cmp	[prev_num_colors], 0x100
1293
	ja	.rgb
1294
	mov	eax, [background_color]
1295
	mov	edi, [prev_palette]
1296
	mov	ecx, [prev_num_colors]
1297
	repnz	scasd
1298
	jz	.palette_ok
1299
	cmp	[prev_num_colors], 0x100
1300
	jz	.convert_rgb
1301
	push	1
1302
	pop	eax
1303
	stdcall	img.decode.gif._.alloc_aux_img
1304
	test	eax, eax
1305
	jz	.previous
1306
	mov	ecx, [prev_num_colors]
1307
	mov	esi, [prev_palette]
1308
	call	img.decode.gif._.alloc_aux_palette
1309
	test	eax, eax
1310
	jz	.previous
1311
	mov	[prev_palette], eax
1312
	mov	eax, [background_color]
1313
	stosd
1314
	mov	eax, [prev_num_colors]	; eax = index of background color
1315
	inc	[prev_num_colors]
1316
	jmp	.bpp8_common
1317
.palette_ok:
1318
	push	1
1319
	pop	eax
1320
	stdcall	img.decode.gif._.alloc_aux_img
1321
	test	eax, eax
1322
	jz	.previous
1323
	sub	edi, [prev_palette]
1324
	shr	edi, 2
1325
	lea	eax, [edi-1]	; eax = index of background color
1326
.bpp8_common:
1327
	push	eax
1328
	mov	ebx, [_data]
1329
	mov	esi, [prev_img_data]
1330
	mov	edi, [aux_img_data]
1331
	mov	[prev_img_data], edi
1332
	cmp	esi, edi
1333
	jz	@f
1334
	movzx	ecx, [ebx + gif.Header.lsd.ScreenWidth]
1335
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1336
	imul	ecx, eax
1337
	push	edi
1338
	rep	movsb
1339
	pop	edi
1340
@@:
1341
	movzx	esi, [ebx + gif.Header.lsd.ScreenHeight]
1342
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1343
	mov	edx, [edx + Image.Extended]
1344
	movzx	ecx, [edx + gif.Image.info.Top]
1345
	sub	esi, ecx
1346
	jbe	.bpp8_ret
1347
	imul	ecx, eax
1348
	add	edi, ecx
1349
	cmp	si, [edx + gif.Image.info.Height]
1350
	jb	@f
1351
	mov	si, [edx + gif.Image.info.Height]
1352
@@:
1353
	movzx	ecx, [edx + gif.Image.info.Left]
1354
	sub	eax, ecx
1355
	jbe	.bpp8_ret
1356
	add	edi, ecx
1357
	cmp	ax, [edx + gif.Image.info.Width]
1358
	jb	@f
1359
	mov	ax, [edx + gif.Image.info.Width]
1360
@@:
1361
	xchg	eax, ecx
1362
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1363
	sub	edx, ecx
1364
	pop	eax
1365
@@:
1366
	push	ecx
1367
	rep	stosb
1368
	pop	ecx
1369
	add	edi, edx
1370
	dec	esi
1371
	jnz	@b
1372
	push	eax
1373
.bpp8_ret:
1374
	pop	eax
1375
	retn
1376
.convert_rgb:
1377
	push	3
1378
	pop	eax
1379
	stdcall	img.decode.gif._.alloc_aux_img
1380
	test	eax, eax
1381
	jz	.previous
1382
	or	[prev_num_colors], -1
1383
	mov	ebx, [_data]
1384
	mov	esi, [prev_img_data]
1385
	mov	edi, [aux_img_data]
1386
	mov	[prev_img_data], edi
1387
	movzx	ecx, [ebx + gif.Header.lsd.ScreenWidth]
1388
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1389
	imul	ecx, eax
1390
	push	edx
1391
	xor	edx, edx
1392
	xchg	edx, [prev_palette]
1393
	add	edi, ecx
1394
	add	esi, ecx
1395
	add	edi, ecx
1396
	add	edi, ecx
1397
@@:
1398
	dec	esi
1399
	movzx	eax, byte [esi]
1400
	mov	eax, [eax*4+edx]
1401
	sub	edi, 3
1402
	mov	[edi], ax
1403
	shr	eax, 16
1404
	mov	[edi+2], al
1405
	loop	@b
1406
	pop	edx
1407
	movzx	esi, [ebx + gif.Header.lsd.ScreenHeight]
1408
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1409
	mov	edx, [edx + Image.Extended]
1410
	movzx	ecx, [edx + gif.Image.info.Top]
1411
	sub	esi, ecx
1412
	jbe	.convert_rgb_ret
1413
	imul	ecx, eax
1414
	lea	ecx, [ecx*3]
1415
	add	edi, ecx
1416
	cmp	si, [edx + gif.Image.info.Height]
1417
	jb	@f
1418
	mov	si, [edx + gif.Image.info.Height]
1419
@@:
1420
	movzx	ecx, [edx + gif.Image.info.Left]
1421
	sub	eax, ecx
1422
	jbe	.convert_rgb_ret
1423
	lea	ecx, [ecx*3]
1424
	add	edi, ecx
1425
	cmp	ax, [edx + gif.Image.info.Width]
1426
	jb	@f
1427
	mov	ax, [edx + gif.Image.info.Width]
1428
@@:
1429
	xchg	eax, ecx
1430
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1431
	sub	edx, ecx
1432
	mov	eax, [background_color]
1433
	lea	edx, [edx*3]
1434
.convert_rgb_loop:
1435
	push	ecx
1436
@@:
1437
	stosw
1438
	shr	eax, 16
1439
	stosb
1440
	loop	@b
1441
	pop	ecx
1442
	add	edi, edx
1443
	dec	esi
1444
	jnz	.convert_rgb_loop
1445
.convert_rgb_ret:
1446
	retn
1447
.rgb:
1448
	push	3
1449
	pop	eax
1450
	stdcall	img.decode.gif._.alloc_aux_img
1451
	test	eax, eax
1452
	jz	.previous
1453
	or	[prev_num_colors], -1
1454
	and	[prev_palette], 0
1455
	mov	ebx, [_data]
1456
	mov	esi, [prev_img_data]
1457
	mov	edi, [aux_img_data]
1458
	mov	[prev_img_data], edi
1459
	cmp	esi, edi
1460
	jz	@f
1461
	movzx	ecx, [ebx + gif.Header.lsd.ScreenHeight]
1462
	push	ecx
1463
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1464
	imul	ecx, eax
1465
	lea	ecx, [ecx*3]
1466
	push	edi
1467
	rep	movsb
1468
	pop	edi
1469
	pop	esi
1470
	mov	edx, [edx + Image.Extended]
1471
	movzx	ecx, [edx + gif.Image.info.Top]
1472
	sub	esi, ecx
1473
	jbe	.rgb_ret
1474
	imul	ecx, eax
1475
	lea	ecx, [ecx*3]
1476
	add	edi, ecx
1477
	cmp	si, [edx + gif.Image.info.Height]
1478
	jb	@f
1479
	mov	si, [edx + gif.Image.info.Height]
1480
@@:
1481
	movzx	ecx, [edx + gif.Image.info.Left]
1482
	sub	eax, ecx
1483
	jbe	.rgb_ret
1484
	lea	ecx, [ecx*3]
1485
	add	edi, ecx
1486
	cmp	ax, [edx + gif.Image.info.Width]
1487
	jb	@f
1488
	mov	ax, [edx + gif.Image.info.Width]
1489
@@:
1490
	xchg	eax, ecx
1491
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1492
	sub	edx, ecx
1493
	mov	eax, [background_color]
1494
	lea	edx, [edx*3]
1495
.rgb_loop:
1496
	push	ecx
1497
@@:
1498
	stosw
1499
	shr	eax, 16
1500
	stosb
1501
	loop	@b
1502
	pop	ecx
1503
	add	edi, edx
1504
	dec	esi
1505
	jnz	.rgb_loop
1506
.rgb_ret:
1507
	retn
1508
 
1509
endp
1510
 
1511
;;================================================================================================;;
1512
proc img.decode.gif._.alloc_aux_img ;/////////////////////////////////////////////////////////////;;
1513
;;------------------------------------------------------------------------------------------------;;
1514
;? Allocate auxiliary memory for previous image                                                   ;;
1515
;;------------------------------------------------------------------------------------------------;;
1516
;> eax = image type: 1 = bpp8, 3 = bpp24                                                          ;;
1517
;;------------------------------------------------------------------------------------------------;;
1518
;< eax = [aux_img_data]                                                                           ;;
1519
;;================================================================================================;;
1520
	cmp	[aux_img_type], eax
1521
	jae	@f
1522
	push	edx eax
1523
	movzx	ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
1524
	mul	ecx
1525
	movzx	ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
1526
	mul	ecx
1527
	invoke	mem.realloc, [aux_img_data], eax
1528
	pop	ecx edx
1529
	test	eax, eax
1530
	jz	@f
1531
	mov	[aux_img_type], ecx
1532
	mov	[aux_img_data], eax
1533
@@:	retn
1534
 
1535
endp
1536
 
1537
;;================================================================================================;;
1538
proc img.decode.gif._.alloc_aux_palette ;/////////////////////////////////////////////////////////;;
1539
;;------------------------------------------------------------------------------------------------;;
1540
;? Allocate and fill aux_palette                                                                  ;;
1541
;;------------------------------------------------------------------------------------------------;;
1542
;> esi -> palette, ecx = palette size                                                             ;;
1543
;;------------------------------------------------------------------------------------------------;;
1544
;< [aux_palette] set                                                                              ;;
1545
;;================================================================================================;;
1546
	mov	eax, [aux_palette]
1547
	test	eax, eax
1548
	jnz	@f
1549
	push	edx ecx
1550
	invoke	mem.alloc, 0x400
1551
	pop	ecx edx
1552
	test	eax, eax
1553
	jz	.ret
1554
	mov	[aux_palette], eax
1555
@@:
1556
	mov	edi, eax
1557
	rep	movsd
1558
.ret:
1559
	retn
1560
 
1561
endp
1562
 
1563
restore main_img
1564
restore transparent_color
1565
restore background_color
1566
restore prev_num_colors
1567
restore prev_palette
1568
restore max_color
1569
restore prev_img_data
1570
restore _data
1571
restore aux_img_data
1572
restore aux_img_type
1573
restore aux_palette
1574
 
1575
;;================================================================================================;;
1576
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1577
;;================================================================================================;;
1578
;! Below is private data you should never use directly from your code                             ;;
1579
;;================================================================================================;;
1580
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1581
;;================================================================================================;;
1582
 
1583
 
1584
;