Subversion Repositories Kolibri OS

Rev

Rev 2733 | Rev 8394 | 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
276
	shr	eax, 8
277
	stosd
278
	loop	@b
279
	add	ebx, sizeof.gif.ImageDescriptor
280
	stdcall ._.process_image
281
	push	ebx
282
	mov	edx, [img]
283
	push	edx
284
	stdcall	._.superimpose
285
	pop	edx
286
	push	edx
287
	stdcall	._.dispose
288
	pop	edx
289
	mov	edx, [edx + Image.Previous]
290
	test	edx, edx
291
	jz	.nofreeprev
292
	mov	ebx, [edx + Image.Extended]
293
	cmp	[edx + Image.Delay], 0
294
	jnz	.nofreeprev
295
	mov	esi, [prev_palette]
296
	cmp	esi, [edx + Image.Palette]
297
	jnz	@f
298
	mov	ecx, [prev_num_colors]
299
	stdcall	._.alloc_aux_palette
300
	test	eax, eax
301
	jz	.nofreeprev
302
	mov	[prev_palette], eax
303
    @@:
304
	mov	esi, [prev_img_data]
305
	cmp	esi, [edx + Image.Data]
306
	jnz	.noprevdata
307
	push	1
308
	pop	eax
309
	cmp	[edx + Image.Type], Image.bpp8i
310
	jz	@f
311
	mov	al, 3
312
    @@:
313
	cmp	[aux_img_type], eax
314
	jb	.resetaux
315
	mov	edi, [aux_img_data]
316
	imul	eax, [edx + Image.Width]
317
	imul	eax, [edx + Image.Height]
318
	xchg	eax, ecx
319
	rep	movsb
320
	jmp	.noprevdata
321
    .resetaux:
322
	mov	[aux_img_type], eax
323
	mov	eax, [aux_img_data]
324
	test	eax, eax
325
	jz	@f
326
	invoke	mem.free, eax
327
    @@:
328
	xor	eax, eax
329
	xchg	eax, [edx + Image.Data]
330
	mov	[aux_img_data], eax
331
    .noprevdata:
332
	cmp	edx, [main_img]
333
	jnz	@f
334
	mov	eax, [edx + Image.Next]
335
	mov	[main_img], eax
336
	mov	esi, [eax + Image.Extended]
337
	mov	edi, [edx + Image.Extended]
338
	mov	[edx + Image.Extended], esi
339
	mov	[eax + Image.Extended], edi
340
	push	sizeof.gif.Image
341
	pop	ecx
342
	rep	movsb
343
    @@:
344
	stdcall	img.destroy.layer, edx
345
  .nofreeprev:
346
	pop	ebx
347
	test	ebx, ebx
348
	jz	.ret
349
	jmp	.next_image
350
 
351
  .error2:
352
	mov	[img], edx
353
 
354
  .error:
355
	mov	eax, [img]
356
	test	eax, eax
357
	jz	.ret
358
	cmp	[main_img], eax
359
	jnz	@f
360
	and	[main_img], 0
361
  @@:
362
	stdcall	img.destroy.layer, eax
363
  .ret:
364
	mov	eax, [aux_img_data]
365
	test	eax, eax
366
	jz	@f
367
	invoke	mem.free, eax
368
  @@:
369
	mov	eax, [aux_palette]
370
	test	eax, eax
371
	jz	@f
372
	invoke	mem.free, eax
373
  @@:
374
	mov	eax, [main_img]
375
	cmp	[eax + Image.Next], 0
376
	jz	@f
377
	or	[eax + Image.Flags], Image.IsAnimated
378
  @@:
379
	pop	edi esi ebx
380
	ret
381
endp
382
 
383
;;================================================================================================;;
384
proc img.encode.gif _img, _p_length ;/////////////////////////////////////////////////////////////;;
385
;;------------------------------------------------------------------------------------------------;;
386
;? Encode image into raw data in GIF format                                                       ;;
387
;;------------------------------------------------------------------------------------------------;;
388
;> _img = pointer to image                                                                        ;;
389
;;------------------------------------------------------------------------------------------------;;
390
;< eax = 0 (error) or pointer to encoded data                                                     ;;
391
;< _p_length = encoded data length                                                                ;;
392
;;================================================================================================;;
393
	xor	eax, eax
394
	ret
395
endp
396
 
397
 
398
;;================================================================================================;;
399
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
400
;;================================================================================================;;
401
;! Below are private procs you should never call directly from your code                          ;;
402
;;================================================================================================;;
403
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
404
;;================================================================================================;;
405
 
406
 
407
;;================================================================================================;;
408
proc img.decode.gif._.process_extensions ;////////////////////////////////////////////////////////;;
409
;;------------------------------------------------------------------------------------------------;;
410
;? --- TBD ---                                                                                    ;;
411
;;------------------------------------------------------------------------------------------------;;
412
;> ebx = raw image data                                                                           ;;
413
;> edx = image data                                                                               ;;
414
;;------------------------------------------------------------------------------------------------;;
415
;< --- TBD ---                                                                                    ;;
416
;;================================================================================================;;
417
	mov	esi, ebx
418
	xor	eax, eax
419
	mov	[edx + Image.Delay], eax
420
 
421
  .next_block:
422
	dec	[img.decode.gif._length]
423
	js	.exit_err
424
	lodsb	; load gif.Block.Introducer
425
	cmp	al, gif.Block.Introducer.Extension
426
	jne	.exit
427
 
428
  .ext_block:
429
	dec	[img.decode.gif._length]
430
	js	.exit_err
431
	lodsb	; load gif.Extension.Label
432
	cmp	al, gif.Extension.Label.GraphicsControl
433
	je	.graphics_control_ext
434
;	cmp	al, gif.Extension.Label.PlainText
435
;	je	.plain_text_ext
436
;	cmp	al, gif.Extension.Label.Comment
437
;	je	.comment_ext
438
;	cmp	al, gif.Extension.Label.Application
439
;	je	.application_ext
440
; skip all other extensions
441
  .skip_ext:
442
	dec	[img.decode.gif._length]
443
	js	.exit_err
444
	lodsb	; load BlockSize
445
  .1:
446
	test	al, al
447
	jz	.next_block
448
	sub	[img.decode.gif._length], eax
449
	jc	.exit_err
450
	add	esi, eax
451
	jmp	.skip_ext
452
 
453
  .graphics_control_ext:
454
	dec	[img.decode.gif._length]
455
	js	.exit_err
456
	lodsb	; load BlockSize; must be sizeof.gif.GraphicsControlExtension
457
	cmp	al, sizeof.gif.GraphicsControlExtension
458
	jnz	.1
459
	sub	[img.decode.gif._length], eax
460
	jc	.exit_err
461
	push	edi
462
	movzx	edi, [esi + gif.GraphicsControlExtension.DelayTime]
463
	mov	[edx + Image.Delay], edi
464
	mov	edi, [edx + Image.Extended]
465
	add	edi, gif.Image.gce
466
	mov	ecx, eax
467
	rep	movsb
468
	pop	edi
469
	jmp	.skip_ext
470
 
471
  .exit_err:
472
	xor	eax, eax
473
 
474
  .exit:
475
	mov	ebx, esi
476
	ret
477
endp
478
 
479
;;================================================================================================;;
480
proc img.decode.gif._.process_image ;/////////////////////////////////////////////////////////////;;
481
;;------------------------------------------------------------------------------------------------;;
482
;? --- TBD ---                                                                                    ;;
483
;;------------------------------------------------------------------------------------------------;;
484
;> ebx = raw image data                                                                           ;;
485
;> edx = image data                                                                               ;;
486
;;------------------------------------------------------------------------------------------------;;
487
;< --- TBD ---                                                                                    ;;
488
;;================================================================================================;;
489
locals
490
  width      dd ?
491
  img_start  dd ?
492
  img_end    dd ?
493
  row_end    dd ?
494
  pass	     dd ?
495
  codesize   dd ?
496
  compsize   dd ?
497
  workarea   dd ?
498
  block_ofs  dd ?
499
  bit_count  dd ?
500
  CC	     dd ?
501
  EOI	     dd ?
502
endl
503
 
504
	invoke	mem.alloc, 16 * 1024
505
	mov	[workarea], eax
506
	or	eax, eax
507
	jz	.error
508
 
509
	mov	ecx, [edx + Image.Width]
510
	mov	[width], ecx
511
	mov	eax, [edx + Image.Height]
512
	imul	eax, ecx
513
	mov	[img_end], eax
514
	inc	eax
515
	mov	[row_end], eax
516
	and	[pass], 0
517
	and	dword [img.decode.gif.max_color_child], 0
518
	mov	eax, [edx + Image.Extended]
519
	test	[eax + gif.Image.info.Packed], gif.ID.Packed.InterleaceFlag
520
	jz	@f
521
	mov	[row_end], ecx
522
 
523
    @@: mov	esi, ebx
524
	mov	edi, [edx + Image.Data]
525
 
526
	sub	dword [img.decode.gif._length_child], 2
527
	jc	.error
528
	movzx	ecx, byte[esi]
529
	inc	esi
530
	cmp	cl, 12
531
	jae	.error
532
	mov	[codesize], ecx
533
	inc	[codesize]
534
	xor	eax, eax
535
	lodsb				; eax - block_count
536
	sub	[img.decode.gif._length_child], eax
537
	jc	.error
538
	add	eax, esi
539
	push	edi
540
	mov	edi, [workarea]
541
	mov	[block_ofs], eax
542
	mov	[bit_count], 8
543
	mov	eax, 1
544
	shl	eax, cl
545
	mov	[CC], eax
546
	mov	ecx, eax
547
	inc	eax
548
	mov	[EOI], eax
549
	mov	eax, gif.Null shl 16
550
  .filltable:
551
	stosd
552
	inc	eax
553
	loop	.filltable
554
	pop	edi
555
	mov	[img_start], edi
556
	add	[img_end], edi
557
	add	[row_end], edi
558
  .reinit:
559
	mov	edx, [EOI]
560
	inc	edx
561
	push	[codesize]
562
	pop	[compsize]
563
	call	.get_symbol
564
	cmp	eax, [CC]
565
	je	.reinit
566
	call	.output
567
  .cycle:
568
	movzx	ebx, ax
569
	call	.get_symbol
570
	cmp	eax, [EOI]
571
	je	.end
572
	cmp	eax, edx
573
	ja	.error
574
	je	.notintable
575
	cmp	eax, [CC]
576
	je	.reinit
577
	call	.output
578
  .add:
579
	cmp	edx, 0x00001000
580
	jae	.cycle
581
	mov	ecx, [workarea]
582
	mov	[ecx + edx * 4], ebx
583
	inc	edx
584
	cmp	edx, 0x1000
585
	je	.noinc
586
	bsr	ebx, edx
587
	cmp	ebx, [compsize]
588
	jne	.noinc
589
	inc	[compsize]
590
  .noinc:
591
	jmp	.cycle
592
  .notintable:
593
	push	eax
594
	mov	eax, ebx
595
	call	.output
596
	push	ebx
597
	movzx	eax, bx
598
	call	.output
599
	pop	ebx eax
600
	jmp	.add
601
  .end:
602
	mov	edi, [img_end]
603
	xor	eax, eax
604
 
605
  .exit:
606
	cmp	[workarea], 0
607
	je	@f
608
	invoke	mem.free, [workarea]
609
    @@:
610
	mov	ebx, [block_ofs]
611
    @@:
612
	dec	[img.decode.gif._length_child]
613
	js	@f
614
	movzx	eax, byte [ebx]
615
	inc	ebx
616
	test	eax, eax
617
	jz	.ret
618
	sub	[img.decode.gif._length_child], eax
619
	jc	@f
620
	add	ebx, eax
621
	jmp	@b
622
 
623
  .error:
624
	cmp	[workarea], 0
625
	je	@f
626
	invoke	mem.free, [workarea]
627
    @@: xor	ebx, ebx
628
  .ret:
629
	ret
630
 
631
;;------------------------------------------------------------------------------------------------;;
632
 
633
img.decode.gif._.process_image.get_symbol:
634
	mov	ecx, [compsize]
635
	push	ecx
636
	xor	eax, eax
637
 
638
  .shift:
639
	dec	[bit_count]
640
	jns	.loop1
641
	inc	esi
642
	cmp	esi, [block_ofs]
643
	jb	.noblock
644
	push	eax
645
	xor	eax, eax
646
	sub	[img.decode.gif._length_child], 1
647
	jc	.error_eof
648
	lodsb
649
	test	eax, eax
650
	jnz	.nextbl
651
  .error_eof:
652
	add	esp, 12
653
	jmp	img.decode.gif._.process_image.error
654
 
655
  .nextbl:
656
	sub	[img.decode.gif._length_child], eax
657
	jc	.error_eof
658
	add	eax, esi
659
	mov	[block_ofs], eax
660
	pop	eax
661
 
662
  .noblock:
663
	mov	[bit_count], 7
664
 
665
  .loop1:
666
	ror	byte[esi], 1
667
	rcr	eax,1
668
	loop	.shift
669
	pop	ecx
670
	rol	eax, cl
671
 
672
  .exit:
673
	xor	ecx, ecx
674
	retn
675
 
676
;;------------------------------------------------------------------------------------------------;;
677
 
678
img.decode.gif._.process_image.output:
679
	push	esi eax edx
680
	mov	edx, [workarea]
681
 
682
  .next:
683
	pushw	[edx + eax * 4]
684
	mov	ax, [edx + eax * 4 + 2]
685
	inc	ecx
686
	cmp	ax, gif.Null
687
	jnz	.next
688
	shl	ebx, 16
689
	mov	bx, [esp]
690
 
691
  .loop2:
692
	pop	ax
693
	cmp	al, byte [img.decode.gif.cur_color_table_size_child]
694
	jbe	@f	; guard against incorrect GIFs
695
	mov	al, 0
696
    @@: cmp	al, byte [img.decode.gif.max_color_child]
697
	jbe	@f
698
	mov	[img.decode.gif.max_color_child], al
699
    @@:	stosb
700
 
701
	cmp	edi, [row_end]
702
	jb	.norowend
703
	mov	eax, [width]
704
	push	eax
705
	sub	edi, eax
706
	add	eax, eax
707
	cmp	[pass], 3
708
	je	@f
709
	add	eax, eax
710
	cmp	[pass], 2
711
	je	@f
712
	add	eax, eax
713
    @@: add	edi, eax
714
	pop	eax
715
	cmp	edi, [img_end]
716
	jb	.nextrow
717
	mov	edi, [img_start]
718
	inc	[pass]
719
	cmp	[pass], 4
720
	je	.done
721
	add	edi, eax
722
	cmp	[pass], 3
723
	je	@f
724
	add	edi, eax
725
	cmp	[pass], 2
726
	je	@f
727
	add	edi, eax
728
	add	edi, eax
729
    @@:
730
 
731
  .nextrow:
732
	add	eax, edi
733
	mov	[row_end], eax
734
	xor	eax, eax
735
 
736
  .norowend:
737
	cmp	edi, [img_end]
738
	jz	.done
739
	loop	.loop2
740
	pop	edx eax esi
741
	retn
742
 
743
  .done:
744
	lea	esp, [esp+(ecx-1)*2]
745
	pop	edx eax esi eax
746
	jmp	img.decode.gif._.process_image.exit
747
 
748
endp
749
 
750
;;================================================================================================;;
751
proc img.decode.gif._.is_logical_screen ;/////////////////////////////////////////////////////////;;
752
;;------------------------------------------------------------------------------------------------;;
753
;? Determines whether GIF image occupies the whole logical screen                                 ;;
754
;;------------------------------------------------------------------------------------------------;;
755
;> eax = extended image data                                                                      ;;
756
;> ebx = main image                                                                               ;;
757
;;------------------------------------------------------------------------------------------------;;
758
;< ZF set <=> image area equals logical screen                                                    ;;
759
;;================================================================================================;;
760
	mov	ebx, [ebx + Image.Extended]
761
	cmp	[eax + gif.Image.info.Left], 0
762
	jnz	@f
763
	cmp	[eax + gif.Image.info.Top], 0
764
	jnz	@f
765
	mov	cx, [eax + gif.Image.info.Width]
766
	cmp	cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
767
	jnz	@f
768
	mov	cx, [eax + gif.Image.info.Height]
769
	cmp	cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
770
@@:	retn
771
endp
772
 
773
main_img equ img.decode.gif.main_img
774
transparent_color equ img.decode.gif.transparent_color
775
background_color equ img.decode.gif.background_color
776
prev_num_colors equ img.decode.gif.prev_num_colors
777
prev_palette equ img.decode.gif.prev_palette
778
max_color equ img.decode.gif.max_color
779
prev_img_data equ img.decode.gif.prev_img_data
780
_data equ img.decode.gif._data
781
aux_img_data equ img.decode.gif.aux_img_data
782
aux_img_type equ img.decode.gif.aux_img_type
783
aux_palette equ img.decode.gif.aux_palette
784
 
785
;;================================================================================================;;
786
proc img.decode.gif._.superimpose ;///////////////////////////////////////////////////////////////;;
787
;;------------------------------------------------------------------------------------------------;;
788
;? --- TBD ---                                                                                    ;;
789
;;------------------------------------------------------------------------------------------------;;
790
;> edx = image data                                                                               ;;
791
;;------------------------------------------------------------------------------------------------;;
792
;< --- TBD ---                                                                                    ;;
793
;;================================================================================================;;
794
	mov	ebx, [main_img]
795
	mov	eax, [edx + Image.Extended]
796
	or	[transparent_color], -1		; no transparent color
797
	test	byte [eax + gif.Image.gce.Packed], 1
798
	jz	@f
799
	movzx	ecx, byte [eax + gif.Image.gce.ColorIndex]
800
	mov	[transparent_color], ecx
801
	cmp	edx, ebx
802
	jnz	.has_transparency
803
	shl	ecx, 2
804
	add	ecx, [edx + Image.Palette]
805
	push	eax
806
	mov	eax, [img.decode.gif.options_bgr]
807
	mov	dword [background_color], eax
808
	mov	dword [ecx], eax
809
	pop	eax
810
@@:
811
	call	img.decode.gif._.is_logical_screen
812
	jnz	.has_transparency
813
; image is not transparent, so keep it as is
814
	retn
815
 
816
.has_transparency:
817
; image has transparent areas, we must superimpose it on the previous
818
	mov	ecx, [prev_num_colors]
819
	cmp	ecx, 0x100
820
	ja	.superimpose_on_rgb
821
; create common palette
822
	sub	esp, 3FCh
823
	push	eax
824
	mov	edi, esp
825
	push	ecx
826
	mov	esi, [prev_palette]
827
	rep	movsd
828
	pop	ecx
829
	mov	esi, [edx + Image.Palette]
830
	xor	ebx, ebx
831
	mov	edi, esp
832
	sub	esp, 100h
833
.create_palette_loop:
834
	push	ecx
835
	lodsd
836
	cmp	ebx, [transparent_color]
837
	jz	.nochange
838
	cmp	ebx, ecx
839
	jae	@f
840
	cmp	eax, [edi+ebx*4]
841
	jz	.nochange
842
@@:
843
	push	edi
844
	repnz	scasd
845
	pop	edi
846
	jnz	.increase_palette
847
	sub	ecx, [esp]
848
	not	ecx	; cl = index of new color in current palette
849
	jmp	.palette_common
850
.increase_palette:
851
	mov	ecx, [esp]
852
	test	ch, ch
853
	jnz	.output_to_rgb
854
	inc	dword [esp]
855
	mov	[edi+ecx*4], eax
856
	jmp	.palette_common
857
.nochange:
858
	mov	ecx, ebx
859
.palette_common:
860
	mov	[ebx+esp+4], cl
861
	pop	ecx
862
	inc	ebx
863
	cmp	ebx, [max_color]
864
	jbe	.create_palette_loop
865
	mov	[max_color], ecx
866
; if image occupies only part of logical screen, allocate memory for full logical screen
867
	mov	ebx, [main_img]
868
	mov	eax, [edx + Image.Extended]
869
	mov	esi, [edx + Image.Data]
870
	call	img.decode.gif._.is_logical_screen
871
	jz	@f
872
	and	[edx + Image.Data], 0
873
	push	edx
874
	movzx	eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
875
	push	eax
876
	movzx	eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
877
	stdcall	img._.resize_data, edx, eax
878
	pop	edx
879
	test	eax, eax
880
	jz	.palette_nomem
881
@@:
882
; copy final palette to Image.Palette
883
	push	esi esi
884
	mov	esi, edi
885
	mov	edi, [edx + Image.Palette]
886
	mov	ecx, [max_color]
887
	dec	[max_color]
888
	rep	movsd
889
	mov	esi, [prev_img_data]
890
	mov	edi, [edx + Image.Data]
891
; do superimpose, [esp] -> source data, esi -> prev image data
892
;   (NULL if previous image is filled with background color), esp+8 -> correspondence between
893
;   used palette and final palette, edi -> destination data
894
	mov	ebx, [edx + Image.Extended]
895
; first Top rows are copied from [prev_img_data] or filled with bgr
896
	movzx	ecx, [ebx + gif.Image.info.Top]
897
	cmp	ecx, [edx + Image.Height]
898
	jb	@f
899
	mov	ecx, [edx + Image.Height]
900
@@:
901
	push	ecx
902
	imul	ecx, [edx + Image.Width]
903
	call	.rep_movsb_or_stosb
904
	pop	ecx
905
; convert rows
906
	sub	ecx, [edx + Image.Height]
907
	neg	ecx
908
	push	ecx
909
	cmp	cx, [ebx + gif.Image.info.Height]
910
	jbe	@f
911
	mov	cx, [ebx + gif.Image.info.Height]
912
@@:
913
	jecxz	.norows
914
.convert_rows:
915
	push	ecx
916
	movzx	ecx, [ebx + gif.Image.info.Left]
917
	cmp	ecx, [edx + Image.Width]
918
	jb	@f
919
	mov	ecx, [edx + Image.Width]
920
@@:
921
	push	ecx
922
	call	.rep_movsb_or_stosb
923
	pop	ecx
924
	sub	ecx, [edx + Image.Width]
925
	neg	ecx
926
	push	ecx edx
927
	mov	edx, [esp+16]	; source data
928
	cmp	cx, [ebx + gif.Image.info.Width]
929
	jbe	@f
930
	mov	cx, [ebx + gif.Image.info.Width]
931
@@:
932
	jecxz	.norowsi
933
.rowsloop:
934
	movzx	eax, byte [edx]
935
	inc	edx
936
	cmp	eax, [transparent_color]
937
	jz	.rows_transparent
938
	mov	al, [eax+esp+24]
939
	stosb
940
	call	.lodsb
941
	jmp	@f
942
.rows_transparent:
943
	call	.lodsb
944
	stosb
945
@@:
946
	loop	.rowsloop
947
.norowsi:
948
	pop	edx ecx
949
	sub	cx, [ebx + gif.Image.info.Width]
950
	jbe	@f
951
	call	.rep_movsb_or_stosb
952
@@:
953
	movzx	eax, [ebx + gif.Image.info.Width]
954
	add	[esp+8], eax
955
	pop	ecx
956
	loop	.convert_rows
957
.norows:
958
	pop	ecx
959
	sub	cx, [ebx + gif.Image.info.Height]
960
	jbe	@f
961
	imul	ecx, [edx + Image.Width]
962
	call	.rep_movsb_or_stosb
963
@@:
964
; free old image data if we have allocated new copy
965
	pop	esi esi
966
	cmp	esi, [edx + Image.Data]
967
	jz	@f
968
	invoke	mem.free, esi
969
@@:
970
; cleanup stack and return
971
	add	esp, 500h
972
	retn
973
.palette_nomem:
974
	mov	[edx + Image.Data], esi
975
	jmp	@b
976
 
977
.output_to_rgb:
978
	pop	ecx
979
	add	esp, 500h
980
; compose two palette-based images to one RGB image
981
	xor	esi, esi
982
	xchg	esi, [edx + Image.Data]
983
	push	esi
984
	mov	ebx, [_data]
985
	push	[edx + Image.Palette]
986
	mov	byte [edx + Image.Type], Image.bpp24
987
	push	edx
988
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
989
	push	eax
990
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
991
	stdcall	img._.resize_data, edx, eax
992
	pop	edx
993
	test	eax, eax
994
	jz	.convrgb_nomem
995
	push	esi
996
	mov	edi, [edx + Image.Data]
997
	mov	esi, [prev_img_data]
998
	mov	ebx, [edx + Image.Extended]
999
; first Top rows are copied from [prev_img_data] or filled with bgr
1000
	movzx	ecx, [ebx + gif.Image.info.Top]
1001
	cmp	ecx, [edx + Image.Height]
1002
	jb	@f
1003
	mov	ecx, [edx + Image.Height]
1004
@@:
1005
	push	ecx
1006
	imul	ecx, [edx + Image.Width]
1007
	call	.convrgb_prev
1008
	pop	ecx
1009
; convert rows
1010
	sub	ecx, [edx + Image.Height]
1011
	neg	ecx
1012
	push	ecx
1013
	cmp	cx, [ebx + gif.Image.info.Height]
1014
	jbe	@f
1015
	mov	cx, [ebx + gif.Image.info.Height]
1016
@@:
1017
	jecxz	.convrgb_norows
1018
.convrgb_convert_rows:
1019
	push	ecx
1020
	movzx	ecx, [ebx + gif.Image.info.Left]
1021
	cmp	ecx, [edx + Image.Width]
1022
	jb	@f
1023
	mov	ecx, [edx + Image.Width]
1024
@@:
1025
	push	ecx
1026
	call	.convrgb_prev
1027
	pop	ecx
1028
	sub	ecx, [edx + Image.Width]
1029
	neg	ecx
1030
	push	ecx edx
1031
	mov	edx, [esp+16]	; source data
1032
	cmp	cx, [ebx + gif.Image.info.Width]
1033
	jbe	@f
1034
	mov	cx, [ebx + gif.Image.info.Width]
1035
@@:
1036
	jecxz	.convrgb_norowsi
1037
.convrgb_rowsloop:
1038
	movzx	eax, byte [edx]
1039
	inc	edx
1040
	cmp	eax, [transparent_color]
1041
	jz	.convrgb_rows_transparent
1042
	shl	eax, 2
1043
	add	eax, [esp+20]	; source palette
1044
	mov	eax, [eax]
1045
	stosw
1046
	shr	eax, 16
1047
	stosb
1048
	call	.convrgb_lodsb
1049
	jmp	@f
1050
.convrgb_rows_transparent:
1051
	call	.convrgb_lodsb
1052
	stosw
1053
	shr	eax, 16
1054
	stosb
1055
@@:
1056
	loop	.convrgb_rowsloop
1057
.convrgb_norowsi:
1058
	pop	edx ecx
1059
	sub	cx, [ebx + gif.Image.info.Width]
1060
	jbe	@f
1061
	call	.convrgb_prev
1062
@@:
1063
	movzx	eax, [ebx + gif.Image.info.Width]
1064
	add	[esp+8], eax
1065
	pop	ecx
1066
	loop	.convrgb_convert_rows
1067
.convrgb_norows:
1068
	pop	ecx
1069
	sub	cx, [ebx + gif.Image.info.Height]
1070
	jbe	@f
1071
	imul	ecx, [edx + Image.Width]
1072
	call	.convrgb_prev
1073
@@:
1074
; free old image data
1075
	pop	esi esi ;esi
1076
	invoke	mem.free;, esi
1077
	retn
1078
.convrgb_nomem:
1079
	pop	esi esi
1080
	retn
1081
 
1082
.superimpose_on_rgb:
1083
; previous image is RGB, new image has transparent areas
1084
	xor	esi, esi
1085
	xchg	esi, [edx + Image.Data]
1086
	push	esi
1087
	mov	ebx, [_data]
1088
	push	[edx + Image.Palette]
1089
	mov	byte [edx + Image.Type], Image.bpp24
1090
	push	edx
1091
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1092
	push	eax
1093
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1094
	stdcall	img._.resize_data, edx, eax
1095
	pop	edx
1096
	test	eax, eax
1097
	jz	.rgb_nomem
1098
	push	esi
1099
	mov	edi, [edx + Image.Data]
1100
	mov	esi, [prev_img_data]
1101
	mov	ebx, [edx + Image.Extended]
1102
; first Top rows are copied from [prev_img_data] or filled with bgr
1103
	movzx	ecx, [ebx + gif.Image.info.Top]
1104
	cmp	ecx, [edx + Image.Height]
1105
	jb	@f
1106
	mov	ecx, [edx + Image.Height]
1107
@@:
1108
	push	ecx
1109
	lea	ecx, [ecx*3]
1110
	imul	ecx, [edx + Image.Width]
1111
	rep	movsb
1112
	pop	ecx
1113
; convert rows
1114
	sub	ecx, [edx + Image.Height]
1115
	neg	ecx
1116
	push	ecx
1117
	cmp	cx, [ebx + gif.Image.info.Height]
1118
	jbe	@f
1119
	mov	cx, [ebx + gif.Image.info.Height]
1120
@@:
1121
	jecxz	.rgb_norows
1122
.rgb_convert_rows:
1123
	push	ecx
1124
	movzx	ecx, [ebx + gif.Image.info.Left]
1125
	cmp	ecx, [edx + Image.Width]
1126
	jb	@f
1127
	mov	ecx, [edx + Image.Width]
1128
@@:
1129
	push	ecx
1130
	lea	ecx, [ecx*3]
1131
	rep	movsb
1132
	pop	ecx
1133
	sub	ecx, [edx + Image.Width]
1134
	neg	ecx
1135
	push	ecx edx
1136
	mov	edx, [esp+16]	; source data
1137
	cmp	cx, [ebx + gif.Image.info.Width]
1138
	jbe	@f
1139
	mov	cx, [ebx + gif.Image.info.Width]
1140
@@:
1141
	jecxz	.rgb_norowsi
1142
.rgb_rowsloop:
1143
	movzx	eax, byte [edx]
1144
	inc	edx
1145
	cmp	eax, [transparent_color]
1146
	jz	.rgb_rows_transparent
1147
	shl	eax, 2
1148
	add	eax, [esp+20]	; source palette
1149
	mov	eax, [eax]
1150
	stosw
1151
	shr	eax, 16
1152
	stosb
1153
	add	esi, 3
1154
	jmp	@f
1155
.rgb_rows_transparent:
1156
	movsb
1157
	movsb
1158
	movsb
1159
@@:
1160
	loop	.rgb_rowsloop
1161
.rgb_norowsi:
1162
	pop	edx ecx
1163
	sub	cx, [ebx + gif.Image.info.Width]
1164
	jbe	@f
1165
	lea	ecx, [ecx*3]
1166
	rep	movsb
1167
@@:
1168
	movzx	eax, [ebx + gif.Image.info.Width]
1169
	add	[esp+8], eax
1170
	pop	ecx
1171
	loop	.rgb_convert_rows
1172
.rgb_norows:
1173
	pop	ecx
1174
	sub	cx, [ebx + gif.Image.info.Height]
1175
	jbe	@f
1176
	imul	ecx, [edx + Image.Width]
1177
	lea	ecx, [ecx*3]
1178
	rep	movsb
1179
@@:
1180
; free old image data
1181
	pop	esi esi ;esi
1182
	invoke	mem.free;, esi
1183
	retn
1184
.rgb_nomem:
1185
	pop	esi esi
1186
	retn
1187
 
1188
.lodsb:
1189
	xor	eax, eax
1190
	test	esi, esi
1191
	jz	@f
1192
	lodsb
1193
@@:	retn
1194
 
1195
.rep_movsb_or_stosb:
1196
	test	esi, esi
1197
	jz	.rmos1
1198
	rep	movsb
1199
	jmp	.rmos2
1200
.rmos1:	xor	eax, eax	; background index in final palette is 0 in bgr mode
1201
	rep	stosb
1202
.rmos2:	retn
1203
 
1204
.convrgb_prev:
1205
	jecxz	.convrgb_noprev
1206
	test	esi, esi
1207
	jz	.convrgb_prev_bgr
1208
@@:
1209
	xor	eax, eax
1210
	lodsb
1211
	shl	eax, 2
1212
	add	eax, [prev_palette]
1213
	mov	eax, [eax]
1214
	stosw
1215
	shr	eax, 16
1216
	stosb
1217
	loop	@b
1218
	retn
1219
.convrgb_prev_bgr:
1220
@@:
1221
	mov	eax, [background_color]
1222
	stosw
1223
	shr	eax, 16
1224
	stosb
1225
	loop	@b
1226
.convrgb_noprev:
1227
	retn
1228
.convrgb_lodsb:
1229
	xor	eax, eax
1230
	test	esi, esi
1231
	jz	@f
1232
	lodsb
1233
	shl	eax, 2
1234
	add	eax, [prev_palette]
1235
	mov	eax, [eax]
1236
	retn
1237
@@:	mov	eax, [background_color]
1238
	retn
1239
 
1240
endp
1241
 
1242
;;================================================================================================;;
1243
proc img.decode.gif._.dispose ;///////////////////////////////////////////////////////////////////;;
1244
;;------------------------------------------------------------------------------------------------;;
1245
;? --- TBD ---                                                                                    ;;
1246
;;------------------------------------------------------------------------------------------------;;
1247
;> edx = image data                                                                               ;;
1248
;;------------------------------------------------------------------------------------------------;;
1249
;< --- TBD ---                                                                                    ;;
1250
;;================================================================================================;;
1251
	mov	ebx, [edx + Image.Extended]
1252
	mov	al, [ebx + gif.Image.gce.Packed]
1253
	shr	al, 2
1254
	and	al, 7
1255
	cmp	al, 2
1256
	jz	.background
1257
	cmp	al, 3
1258
	jz	.previous
1259
; don't dispose - set prev_img and related vars to current image
1260
	mov	eax, [edx + Image.Data]
1261
	mov	[prev_img_data], eax
1262
	cmp	[edx + Image.Type], Image.bpp8i
1263
	jnz	@f
1264
	mov	eax, [max_color]
1265
	inc	eax
1266
	mov	[prev_num_colors], eax
1267
	mov	eax, [edx + Image.Palette]
1268
	mov	[prev_palette], eax
1269
	retn
1270
@@:
1271
	or	[prev_num_colors], -1
1272
	and	[prev_palette], 0
1273
.previous:
1274
	retn
1275
.background:
1276
	cmp	[prev_img_data], 0
1277
	jz	.bgr_full
1278
	mov	ebx, [main_img]
1279
	mov	eax, [edx + Image.Extended]
1280
	call	img.decode.gif._.is_logical_screen
1281
	jnz	@f
1282
.bgr_full:
1283
	xor	eax, eax
1284
	mov	[prev_img_data], eax
1285
	inc	eax
1286
	mov	[prev_num_colors], eax
1287
	lea	eax, [background_color]
1288
	mov	[prev_palette], eax
1289
	retn
1290
@@:
1291
	cmp	[prev_num_colors], 0x100
1292
	ja	.rgb
1293
	mov	eax, [background_color]
1294
	mov	edi, [prev_palette]
1295
	mov	ecx, [prev_num_colors]
1296
	repnz	scasd
1297
	jz	.palette_ok
1298
	cmp	[prev_num_colors], 0x100
1299
	jz	.convert_rgb
1300
	push	1
1301
	pop	eax
1302
	stdcall	img.decode.gif._.alloc_aux_img
1303
	test	eax, eax
1304
	jz	.previous
1305
	mov	ecx, [prev_num_colors]
1306
	mov	esi, [prev_palette]
1307
	call	img.decode.gif._.alloc_aux_palette
1308
	test	eax, eax
1309
	jz	.previous
1310
	mov	[prev_palette], eax
1311
	mov	eax, [background_color]
1312
	stosd
1313
	mov	eax, [prev_num_colors]	; eax = index of background color
1314
	inc	[prev_num_colors]
1315
	jmp	.bpp8_common
1316
.palette_ok:
1317
	push	1
1318
	pop	eax
1319
	stdcall	img.decode.gif._.alloc_aux_img
1320
	test	eax, eax
1321
	jz	.previous
1322
	sub	edi, [prev_palette]
1323
	shr	edi, 2
1324
	lea	eax, [edi-1]	; eax = index of background color
1325
.bpp8_common:
1326
	push	eax
1327
	mov	ebx, [_data]
1328
	mov	esi, [prev_img_data]
1329
	mov	edi, [aux_img_data]
1330
	mov	[prev_img_data], edi
1331
	cmp	esi, edi
1332
	jz	@f
1333
	movzx	ecx, [ebx + gif.Header.lsd.ScreenWidth]
1334
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1335
	imul	ecx, eax
1336
	push	edi
1337
	rep	movsb
1338
	pop	edi
1339
@@:
1340
	movzx	esi, [ebx + gif.Header.lsd.ScreenHeight]
1341
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1342
	mov	edx, [edx + Image.Extended]
1343
	movzx	ecx, [edx + gif.Image.info.Top]
1344
	sub	esi, ecx
1345
	jbe	.bpp8_ret
1346
	imul	ecx, eax
1347
	add	edi, ecx
1348
	cmp	si, [edx + gif.Image.info.Height]
1349
	jb	@f
1350
	mov	si, [edx + gif.Image.info.Height]
1351
@@:
1352
	movzx	ecx, [edx + gif.Image.info.Left]
1353
	sub	eax, ecx
1354
	jbe	.bpp8_ret
1355
	add	edi, ecx
1356
	cmp	ax, [edx + gif.Image.info.Width]
1357
	jb	@f
1358
	mov	ax, [edx + gif.Image.info.Width]
1359
@@:
1360
	xchg	eax, ecx
1361
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1362
	sub	edx, ecx
1363
	pop	eax
1364
@@:
1365
	push	ecx
1366
	rep	stosb
1367
	pop	ecx
1368
	add	edi, edx
1369
	dec	esi
1370
	jnz	@b
1371
	push	eax
1372
.bpp8_ret:
1373
	pop	eax
1374
	retn
1375
.convert_rgb:
1376
	push	3
1377
	pop	eax
1378
	stdcall	img.decode.gif._.alloc_aux_img
1379
	test	eax, eax
1380
	jz	.previous
1381
	or	[prev_num_colors], -1
1382
	mov	ebx, [_data]
1383
	mov	esi, [prev_img_data]
1384
	mov	edi, [aux_img_data]
1385
	mov	[prev_img_data], edi
1386
	movzx	ecx, [ebx + gif.Header.lsd.ScreenWidth]
1387
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1388
	imul	ecx, eax
1389
	push	edx
1390
	xor	edx, edx
1391
	xchg	edx, [prev_palette]
1392
	add	edi, ecx
1393
	add	esi, ecx
1394
	add	edi, ecx
1395
	add	edi, ecx
1396
@@:
1397
	dec	esi
1398
	movzx	eax, byte [esi]
1399
	mov	eax, [eax*4+edx]
1400
	sub	edi, 3
1401
	mov	[edi], ax
1402
	shr	eax, 16
1403
	mov	[edi+2], al
1404
	loop	@b
1405
	pop	edx
1406
	movzx	esi, [ebx + gif.Header.lsd.ScreenHeight]
1407
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1408
	mov	edx, [edx + Image.Extended]
1409
	movzx	ecx, [edx + gif.Image.info.Top]
1410
	sub	esi, ecx
1411
	jbe	.convert_rgb_ret
1412
	imul	ecx, eax
1413
	lea	ecx, [ecx*3]
1414
	add	edi, ecx
1415
	cmp	si, [edx + gif.Image.info.Height]
1416
	jb	@f
1417
	mov	si, [edx + gif.Image.info.Height]
1418
@@:
1419
	movzx	ecx, [edx + gif.Image.info.Left]
1420
	sub	eax, ecx
1421
	jbe	.convert_rgb_ret
1422
	lea	ecx, [ecx*3]
1423
	add	edi, ecx
1424
	cmp	ax, [edx + gif.Image.info.Width]
1425
	jb	@f
1426
	mov	ax, [edx + gif.Image.info.Width]
1427
@@:
1428
	xchg	eax, ecx
1429
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1430
	sub	edx, ecx
1431
	mov	eax, [background_color]
1432
	lea	edx, [edx*3]
1433
.convert_rgb_loop:
1434
	push	ecx
1435
@@:
1436
	stosw
1437
	shr	eax, 16
1438
	stosb
1439
	loop	@b
1440
	pop	ecx
1441
	add	edi, edx
1442
	dec	esi
1443
	jnz	.convert_rgb_loop
1444
.convert_rgb_ret:
1445
	retn
1446
.rgb:
1447
	push	3
1448
	pop	eax
1449
	stdcall	img.decode.gif._.alloc_aux_img
1450
	test	eax, eax
1451
	jz	.previous
1452
	or	[prev_num_colors], -1
1453
	and	[prev_palette], 0
1454
	mov	ebx, [_data]
1455
	mov	esi, [prev_img_data]
1456
	mov	edi, [aux_img_data]
1457
	mov	[prev_img_data], edi
1458
	cmp	esi, edi
1459
	jz	@f
1460
	movzx	ecx, [ebx + gif.Header.lsd.ScreenHeight]
1461
	push	ecx
1462
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1463
	imul	ecx, eax
1464
	lea	ecx, [ecx*3]
1465
	push	edi
1466
	rep	movsb
1467
	pop	edi
1468
	pop	esi
1469
	mov	edx, [edx + Image.Extended]
1470
	movzx	ecx, [edx + gif.Image.info.Top]
1471
	sub	esi, ecx
1472
	jbe	.rgb_ret
1473
	imul	ecx, eax
1474
	lea	ecx, [ecx*3]
1475
	add	edi, ecx
1476
	cmp	si, [edx + gif.Image.info.Height]
1477
	jb	@f
1478
	mov	si, [edx + gif.Image.info.Height]
1479
@@:
1480
	movzx	ecx, [edx + gif.Image.info.Left]
1481
	sub	eax, ecx
1482
	jbe	.rgb_ret
1483
	lea	ecx, [ecx*3]
1484
	add	edi, ecx
1485
	cmp	ax, [edx + gif.Image.info.Width]
1486
	jb	@f
1487
	mov	ax, [edx + gif.Image.info.Width]
1488
@@:
1489
	xchg	eax, ecx
1490
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1491
	sub	edx, ecx
1492
	mov	eax, [background_color]
1493
	lea	edx, [edx*3]
1494
.rgb_loop:
1495
	push	ecx
1496
@@:
1497
	stosw
1498
	shr	eax, 16
1499
	stosb
1500
	loop	@b
1501
	pop	ecx
1502
	add	edi, edx
1503
	dec	esi
1504
	jnz	.rgb_loop
1505
.rgb_ret:
1506
	retn
1507
 
1508
endp
1509
 
1510
;;================================================================================================;;
1511
proc img.decode.gif._.alloc_aux_img ;/////////////////////////////////////////////////////////////;;
1512
;;------------------------------------------------------------------------------------------------;;
1513
;? Allocate auxiliary memory for previous image                                                   ;;
1514
;;------------------------------------------------------------------------------------------------;;
1515
;> eax = image type: 1 = bpp8, 3 = bpp24                                                          ;;
1516
;;------------------------------------------------------------------------------------------------;;
1517
;< eax = [aux_img_data]                                                                           ;;
1518
;;================================================================================================;;
1519
	cmp	[aux_img_type], eax
1520
	jae	@f
1521
	push	edx eax
1522
	movzx	ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
1523
	mul	ecx
1524
	movzx	ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
1525
	mul	ecx
1526
	invoke	mem.realloc, [aux_img_data], eax
1527
	pop	ecx edx
1528
	test	eax, eax
1529
	jz	@f
1530
	mov	[aux_img_type], ecx
1531
	mov	[aux_img_data], eax
1532
@@:	retn
1533
 
1534
endp
1535
 
1536
;;================================================================================================;;
1537
proc img.decode.gif._.alloc_aux_palette ;/////////////////////////////////////////////////////////;;
1538
;;------------------------------------------------------------------------------------------------;;
1539
;? Allocate and fill aux_palette                                                                  ;;
1540
;;------------------------------------------------------------------------------------------------;;
1541
;> esi -> palette, ecx = palette size                                                             ;;
1542
;;------------------------------------------------------------------------------------------------;;
1543
;< [aux_palette] set                                                                              ;;
1544
;;================================================================================================;;
1545
	mov	eax, [aux_palette]
1546
	test	eax, eax
1547
	jnz	@f
1548
	push	edx ecx
1549
	invoke	mem.alloc, 0x400
1550
	pop	ecx edx
1551
	test	eax, eax
1552
	jz	.ret
1553
	mov	[aux_palette], eax
1554
@@:
1555
	mov	edi, eax
1556
	rep	movsd
1557
.ret:
1558
	retn
1559
 
1560
endp
1561
 
1562
restore main_img
1563
restore transparent_color
1564
restore background_color
1565
restore prev_num_colors
1566
restore prev_palette
1567
restore max_color
1568
restore prev_img_data
1569
restore _data
1570
restore aux_img_data
1571
restore aux_img_type
1572
restore aux_palette
1573
 
1574
;;================================================================================================;;
1575
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1576
;;================================================================================================;;
1577
;! Below is private data you should never use directly from your code                             ;;
1578
;;================================================================================================;;
1579
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1580
;;================================================================================================;;
1581
 
1582
 
1583
;