Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
717 mikedld 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 ;;
999 diamond 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.                                         ;;
717 mikedld 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  ;;
999 diamond 15
;; Lesser General Public License for more details.                                                ;;
717 mikedld 16
;;                                                                                                ;;
999 diamond 17
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
18
;; If not, see .                                                    ;;
717 mikedld 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
;;================================================================================================;;
1079 diamond 54
	cmp	[_length], sizeof.gif.Header
717 mikedld 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
;;================================================================================================;;
1102 diamond 75
proc img.decode.gif _data, _length, _options ;////////////////////////////////////////////////////;;
717 mikedld 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
1079 diamond 85
  max_color          dd ?
86
  cur_color_table_size dd ?
87
  transparent_color  dd ?
88
  background_color   dd ?
1102 diamond 89
  options_bgr        dd ?
1079 diamond 90
  prev_palette       dd ?
91
  aux_palette        dd ?
717 mikedld 92
  img		     dd ?
1079 diamond 93
  prev_img_data      dd ?
94
  aux_img_data       dd ?
95
  aux_img_type       dd ?
96
  prev_num_colors    dd ?
97
  main_img           dd ?
717 mikedld 98
  global_color_table dd ?
999 diamond 99
  global_color_table_size dd ?
717 mikedld 100
endl
101
 
1079 diamond 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
1102 diamond 114
img.decode.gif.options_bgr equ options_bgr
1079 diamond 115
; offset of _length parameter for child functions with ebp-based frame
116
; child saved ebp, return address, 3 saved registers, 14 local variables
117
img.decode.gif._length_child equ _length + 4 + 4 + 4*3 + 4*14
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
717 mikedld 120
 
1079 diamond 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
1102 diamond 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
1079 diamond 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
 
999 diamond 155
; img.is.gif is called by caller (img.decode)
156
;	stdcall img.is.gif, [_data], [_length]
157
;	or	eax, eax
158
;	jz	.error
717 mikedld 159
 
160
	mov	ebx, [_data]
1079 diamond 161
	sub	[_length], sizeof.gif.Header
717 mikedld 162
 
163
	mov	cl, [ebx + gif.Header.lsd.Packed]
1079 diamond 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
717 mikedld 171
	and	cl, gif.LSD.Packed.SizeOfGlobalColorTableMask
1079 diamond 172
;	shr	cl, gif.LSD.Packed.SizeOfGlobalColorTableShift	; here Shift = 0
173
	push	2
174
	pop	eax
717 mikedld 175
	shl	eax, cl
999 diamond 176
	mov	[global_color_table_size], eax
717 mikedld 177
	lea	eax, [eax * 3]
1079 diamond 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
717 mikedld 186
	add	ebx, eax
1079 diamond 187
    @@:
717 mikedld 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
1079 diamond 204
	push	sizeof.gif.LogicalScreenDescriptor
205
	pop	ecx
999 diamond 206
	test	edx, edx
207
	jz	@f
208
	mov	[edx + Image.Next], eax
1079 diamond 209
	xor	ecx, ecx
210
  @@:
211
	push	eax
999 diamond 212
	mov	[eax + Image.Type], Image.bpp8
717 mikedld 213
 
1079 diamond 214
	add	ecx, sizeof.gif.Image
215
	invoke	mem.alloc, ecx
216
	pop	edx
717 mikedld 217
	or	eax, eax
1079 diamond 218
	jz	.error2
717 mikedld 219
	mov	[edx + Image.Extended], eax
1079 diamond 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
717 mikedld 231
 
232
	stdcall ._.process_extensions
233
 
1079 diamond 234
	cmp	al, gif.Block.Introducer.ImageDescriptor
717 mikedld 235
	jne	.error
1079 diamond 236
	sub	[_length], sizeof.gif.ImageDescriptor
237
	jc	.error
717 mikedld 238
	movzx	eax, [ebx + gif.ImageDescriptor.Width]
239
	movzx	ecx, [ebx + gif.ImageDescriptor.Height]
1079 diamond 240
	push	edx
783 mikedld 241
	stdcall img._.resize_data, [img], eax, ecx
1079 diamond 242
	pop	edx
717 mikedld 243
	or	eax, eax
244
	jz	.error
245
 
999 diamond 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]
717 mikedld 254
	test	[ebx + gif.ImageDescriptor.Packed], gif.ID.Packed.LocalColorTableFlag
255
	jz	@f
999 diamond 256
	lea	esi, [ebx + sizeof.gif.ImageDescriptor]
717 mikedld 257
	mov	cl, [ebx + gif.ImageDescriptor.Packed]
258
	and	cl, gif.ID.Packed.SizeOfLocalColorTableMask
1079 diamond 259
; here Shift = 0
260
;	shr	cl, gif.ID.Packed.SizeOfLocalColorTableShift
261
	push	2
262
	pop	eax
717 mikedld 263
	shl	eax, cl
999 diamond 264
	mov	ecx, eax
265
	lea	eax, [eax*3]
266
	add	ebx, eax
1079 diamond 267
	sub	[_length], eax
268
	jbe	.error	; because we load additional byte, check is 'jbe', not 'jc'
999 diamond 269
@@:
1079 diamond 270
	mov	[cur_color_table_size], ecx
271
	dec	[cur_color_table_size]
272
@@:
999 diamond 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
1079 diamond 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	[ebx + gif.Image.gce.DelayTime], 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.bpp8
717 mikedld 310
	jz	@f
1079 diamond 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
717 mikedld 350
 
1079 diamond 351
  .error2:
352
	mov	[img], edx
353
 
717 mikedld 354
  .error:
999 diamond 355
	mov	eax, [img]
356
	test	eax, eax
1079 diamond 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
999 diamond 366
	jz	@f
1079 diamond 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
717 mikedld 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
1079 diamond 418
	xor	eax, eax
419
	mov	[edx + Image.Delay], eax
717 mikedld 420
 
421
  .next_block:
1079 diamond 422
	dec	[img.decode.gif._length]
423
	js	.exit_err
424
	lodsb	; load gif.Block.Introducer
717 mikedld 425
	cmp	al, gif.Block.Introducer.Extension
1079 diamond 426
	jne	.exit
717 mikedld 427
 
428
  .ext_block:
1079 diamond 429
	dec	[img.decode.gif._length]
430
	js	.exit_err
431
	lodsb	; load gif.Extension.Label
717 mikedld 432
	cmp	al, gif.Extension.Label.GraphicsControl
433
	je	.graphics_control_ext
1079 diamond 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
717 mikedld 452
 
453
  .graphics_control_ext:
1079 diamond 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
717 mikedld 461
	push	edi
1079 diamond 462
	movzx	edi, [esi + gif.GraphicsControlExtension.DelayTime]
463
	mov	[edx + Image.Delay], edi
717 mikedld 464
	mov	edi, [edx + Image.Extended]
465
	add	edi, gif.Image.gce
1079 diamond 466
	mov	ecx, eax
717 mikedld 467
	rep	movsb
468
	pop	edi
1079 diamond 469
	jmp	.skip_ext
717 mikedld 470
 
1079 diamond 471
  .exit_err:
472
	xor	eax, eax
717 mikedld 473
 
474
  .exit:
475
	mov	ebx, esi
476
	ret
477
endp
478
 
479
;;================================================================================================;;
999 diamond 480
proc img.decode.gif._.process_image ;/////////////////////////////////////////////////////////////;;
717 mikedld 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
1079 diamond 517
	and	dword [img.decode.gif.max_color_child], 0
717 mikedld 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
 
1079 diamond 526
	sub	dword [img.decode.gif._length_child], 2
527
	jc	.error
717 mikedld 528
	movzx	ecx, byte[esi]
529
	inc	esi
1079 diamond 530
	cmp	cl, 12
531
	jae	.error
717 mikedld 532
	mov	[codesize], ecx
533
	inc	[codesize]
534
	xor	eax, eax
535
	lodsb				; eax - block_count
1079 diamond 536
	sub	[img.decode.gif._length_child], eax
537
	jc	.error
717 mikedld 538
	add	eax, esi
1079 diamond 539
	push	edi
540
	mov	edi, [workarea]
717 mikedld 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
1079 diamond 570
	cmp	eax, [EOI]
571
	je	.end
717 mikedld 572
	cmp	eax, edx
1079 diamond 573
	ja	.error
574
	je	.notintable
717 mikedld 575
	cmp	eax, [CC]
576
	je	.reinit
577
	call	.output
578
  .add:
1079 diamond 579
	cmp	edx, 0x00001000
580
	jae	.cycle
717 mikedld 581
	mov	ecx, [workarea]
582
	mov	[ecx + edx * 4], ebx
583
	inc	edx
1079 diamond 584
	cmp	edx, 0x1000
585
	je	.noinc
717 mikedld 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]
1079 diamond 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
717 mikedld 622
 
623
  .error:
624
	cmp	[workarea], 0
625
	je	@f
626
	invoke	mem.free, [workarea]
1079 diamond 627
    @@: xor	ebx, ebx
628
  .ret:
717 mikedld 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]
1079 diamond 640
	jns	.loop1
717 mikedld 641
	inc	esi
642
	cmp	esi, [block_ofs]
643
	jb	.noblock
644
	push	eax
645
	xor	eax, eax
1079 diamond 646
	sub	[img.decode.gif._length_child], 1
647
	jc	.error_eof
717 mikedld 648
	lodsb
649
	test	eax, eax
650
	jnz	.nextbl
1079 diamond 651
  .error_eof:
652
	add	esp, 12
653
	jmp	img.decode.gif._.process_image.error
717 mikedld 654
 
655
  .nextbl:
1079 diamond 656
	sub	[img.decode.gif._length_child], eax
657
	jc	.error_eof
717 mikedld 658
	add	eax, esi
659
	mov	[block_ofs], eax
660
	pop	eax
661
 
662
  .noblock:
1079 diamond 663
	mov	[bit_count], 7
717 mikedld 664
 
665
  .loop1:
1079 diamond 666
	ror	byte[esi], 1
667
	rcr	eax,1
717 mikedld 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
1079 diamond 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
717 mikedld 700
 
1079 diamond 701
	cmp	edi, [img_end]
702
	jz	.done
717 mikedld 703
	cmp	edi, [row_end]
704
	jb	.norowend
705
	mov	eax, [width]
706
	push	eax
707
	sub	edi, eax
708
	add	eax, eax
709
	cmp	[pass], 3
710
	je	@f
711
	add	eax, eax
712
	cmp	[pass], 2
713
	je	@f
714
	add	eax, eax
715
    @@: add	edi, eax
716
	pop	eax
717
	cmp	edi, [img_end]
718
	jb	.nextrow
719
	mov	edi, [img_start]
720
	inc	[pass]
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
	loop	.loop2
738
	pop	edx eax esi
739
	retn
740
 
1079 diamond 741
  .done:
742
	lea	esp, [esp+(ecx-1)*2]
743
	pop	edx eax esi eax
744
	jmp	img.decode.gif._.process_image.exit
745
 
717 mikedld 746
endp
747
 
1079 diamond 748
;;================================================================================================;;
749
proc img.decode.gif._.is_logical_screen ;/////////////////////////////////////////////////////////;;
750
;;------------------------------------------------------------------------------------------------;;
751
;? Determines whether GIF image occupies the whole logical screen                                 ;;
752
;;------------------------------------------------------------------------------------------------;;
753
;> eax = extended image data                                                                      ;;
754
;> ebx = main image                                                                               ;;
755
;;------------------------------------------------------------------------------------------------;;
756
;< ZF set <=> image area equals logical screen                                                    ;;
757
;;================================================================================================;;
758
	mov	ebx, [ebx + Image.Extended]
759
	cmp	[eax + gif.Image.info.Left], 0
760
	jnz	@f
761
	cmp	[eax + gif.Image.info.Top], 0
762
	jnz	@f
763
	mov	cx, [eax + gif.Image.info.Width]
764
	cmp	cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
765
	jnz	@f
766
	mov	cx, [eax + gif.Image.info.Height]
767
	cmp	cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
768
@@:	retn
769
endp
717 mikedld 770
 
1079 diamond 771
main_img equ img.decode.gif.main_img
772
transparent_color equ img.decode.gif.transparent_color
773
background_color equ img.decode.gif.background_color
774
prev_num_colors equ img.decode.gif.prev_num_colors
775
prev_palette equ img.decode.gif.prev_palette
776
max_color equ img.decode.gif.max_color
777
prev_img_data equ img.decode.gif.prev_img_data
778
_data equ img.decode.gif._data
779
aux_img_data equ img.decode.gif.aux_img_data
780
aux_img_type equ img.decode.gif.aux_img_type
781
aux_palette equ img.decode.gif.aux_palette
782
 
717 mikedld 783
;;================================================================================================;;
1079 diamond 784
proc img.decode.gif._.superimpose ;///////////////////////////////////////////////////////////////;;
785
;;------------------------------------------------------------------------------------------------;;
786
;? --- TBD ---                                                                                    ;;
787
;;------------------------------------------------------------------------------------------------;;
788
;> edx = image data                                                                               ;;
789
;;------------------------------------------------------------------------------------------------;;
790
;< --- TBD ---                                                                                    ;;
791
;;================================================================================================;;
792
	mov	ebx, [main_img]
793
	mov	eax, [edx + Image.Extended]
794
	or	[transparent_color], -1		; no transparent color
795
	test	byte [eax + gif.Image.gce.Packed], 1
796
	jz	@f
797
	movzx	ecx, byte [eax + gif.Image.gce.ColorIndex]
798
	mov	[transparent_color], ecx
799
	cmp	edx, ebx
800
	jnz	.has_transparency
801
	shl	ecx, 2
802
	add	ecx, [edx + Image.Palette]
1102 diamond 803
	push	eax
804
	mov	eax, [img.decode.gif.options_bgr]
805
	mov	dword [background_color], eax
806
	mov	dword [ecx], eax
807
	pop	eax
1079 diamond 808
@@:
809
	call	img.decode.gif._.is_logical_screen
810
	jnz	.has_transparency
811
; image is not transparent, so keep it as is
812
	retn
813
 
814
.has_transparency:
815
; image has transparent areas, we must superimpose it on the previous
816
	mov	ecx, [prev_num_colors]
817
	cmp	ecx, 0x100
818
	ja	.superimpose_on_rgb
819
; create common palette
820
	sub	esp, 3FCh
821
	push	eax
822
	mov	edi, esp
823
	push	ecx
824
	mov	esi, [prev_palette]
825
	rep	movsd
826
	pop	ecx
827
	mov	esi, [edx + Image.Palette]
828
	xor	ebx, ebx
829
	mov	edi, esp
830
	sub	esp, 100h
831
.create_palette_loop:
832
	push	ecx
833
	lodsd
834
	cmp	ebx, [transparent_color]
835
	jz	.nochange
836
	cmp	ebx, ecx
837
	jae	@f
838
	cmp	eax, [edi+ebx*4]
839
	jz	.nochange
840
@@:
841
	push	edi
842
	repnz	scasd
843
	pop	edi
844
	jnz	.increase_palette
845
	sub	ecx, [esp]
846
	not	ecx	; cl = index of new color in current palette
847
	jmp	.palette_common
848
.increase_palette:
849
	mov	ecx, [esp]
850
	test	ch, ch
851
	jnz	.output_to_rgb
852
	inc	dword [esp]
853
	mov	[edi+ecx*4], eax
854
	jmp	.palette_common
855
.nochange:
856
	mov	ecx, ebx
857
.palette_common:
858
	mov	[ebx+esp+4], cl
859
	pop	ecx
860
	inc	ebx
861
	cmp	ebx, [max_color]
862
	jbe	.create_palette_loop
863
	mov	[max_color], ecx
864
; if image occupies only part of logical screen, allocate memory for full logical screen
865
	mov	ebx, [main_img]
866
	mov	eax, [edx + Image.Extended]
867
	mov	esi, [edx + Image.Data]
868
	call	img.decode.gif._.is_logical_screen
869
	jz	@f
870
	and	[edx + Image.Data], 0
871
	push	edx
872
	movzx	eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
873
	push	eax
874
	movzx	eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
875
	stdcall	img._.resize_data, edx, eax
876
	pop	edx
877
	test	eax, eax
878
	jz	.palette_nomem
879
@@:
880
; copy final palette to Image.Palette
881
	push	esi esi
882
	mov	esi, edi
883
	mov	edi, [edx + Image.Palette]
884
	mov	ecx, [max_color]
885
	dec	[max_color]
886
	rep	movsd
887
	mov	esi, [prev_img_data]
888
	mov	edi, [edx + Image.Data]
889
; do superimpose, [esp] -> source data, esi -> prev image data
890
;   (NULL if previous image is filled with background color), esp+8 -> correspondence between
891
;   used palette and final palette, edi -> destination data
892
	mov	ebx, [edx + Image.Extended]
893
; first Top rows are copied from [prev_img_data] or filled with bgr
894
	movzx	ecx, [ebx + gif.Image.info.Top]
895
	cmp	ecx, [edx + Image.Height]
896
	jb	@f
897
	mov	ecx, [edx + Image.Height]
898
@@:
899
	push	ecx
900
	imul	ecx, [edx + Image.Width]
901
	call	.rep_movsb_or_stosb
902
	pop	ecx
903
; convert rows
904
	sub	ecx, [edx + Image.Height]
905
	neg	ecx
906
	push	ecx
907
	cmp	cx, [ebx + gif.Image.info.Height]
908
	jbe	@f
909
	mov	cx, [ebx + gif.Image.info.Height]
910
@@:
911
	jecxz	.norows
912
.convert_rows:
913
	push	ecx
914
	movzx	ecx, [ebx + gif.Image.info.Left]
915
	cmp	ecx, [edx + Image.Width]
916
	jb	@f
917
	mov	ecx, [edx + Image.Width]
918
@@:
919
	push	ecx
920
	call	.rep_movsb_or_stosb
921
	pop	ecx
922
	sub	ecx, [edx + Image.Width]
923
	neg	ecx
924
	push	ecx edx
925
	mov	edx, [esp+16]	; source data
926
	cmp	cx, [ebx + gif.Image.info.Width]
927
	jbe	@f
928
	mov	cx, [ebx + gif.Image.info.Width]
929
@@:
930
	jecxz	.norowsi
931
.rowsloop:
932
	movzx	eax, byte [edx]
933
	inc	edx
934
	cmp	eax, [transparent_color]
935
	jz	.rows_transparent
936
	mov	al, [eax+esp+24]
937
	stosb
938
	call	.lodsb
939
	jmp	@f
940
.rows_transparent:
941
	call	.lodsb
942
	stosb
943
@@:
944
	loop	.rowsloop
945
.norowsi:
946
	pop	edx ecx
947
	sub	cx, [ebx + gif.Image.info.Width]
948
	jbe	@f
949
	call	.rep_movsb_or_stosb
950
@@:
951
	movzx	eax, [ebx + gif.Image.info.Width]
952
	add	[esp+8], eax
953
	pop	ecx
954
	loop	.convert_rows
955
.norows:
956
	pop	ecx
957
	sub	cx, [ebx + gif.Image.info.Height]
958
	jbe	@f
959
	imul	ecx, [edx + Image.Width]
960
	call	.rep_movsb_or_stosb
961
@@:
962
; free old image data if we have allocated new copy
963
	pop	esi esi
964
	cmp	esi, [edx + Image.Data]
965
	jz	@f
966
	invoke	mem.free, esi
967
@@:
968
; cleanup stack and return
969
	add	esp, 500h
970
	retn
971
.palette_nomem:
972
	mov	[edx + Image.Data], esi
973
	jmp	@b
974
 
975
.output_to_rgb:
976
	pop	ecx
977
	add	esp, 500h
978
; compose two palette-based images to one RGB image
979
	xor	esi, esi
980
	xchg	esi, [edx + Image.Data]
981
	push	esi
982
	mov	ebx, [_data]
983
	push	[edx + Image.Palette]
984
	mov	byte [edx + Image.Type], Image.bpp24
985
	push	edx
986
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
987
	push	eax
988
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
989
	stdcall	img._.resize_data, edx, eax
990
	pop	edx
991
	test	eax, eax
992
	jz	.convrgb_nomem
993
	push	esi
994
	mov	edi, [edx + Image.Data]
995
	mov	esi, [prev_img_data]
996
	mov	ebx, [edx + Image.Extended]
997
; first Top rows are copied from [prev_img_data] or filled with bgr
998
	movzx	ecx, [ebx + gif.Image.info.Top]
999
	cmp	ecx, [edx + Image.Height]
1000
	jb	@f
1001
	mov	ecx, [edx + Image.Height]
1002
@@:
1003
	push	ecx
1004
	imul	ecx, [edx + Image.Width]
1005
	call	.convrgb_prev
1006
	pop	ecx
1007
; convert rows
1008
	sub	ecx, [edx + Image.Height]
1009
	neg	ecx
1010
	push	ecx
1011
	cmp	cx, [ebx + gif.Image.info.Height]
1012
	jbe	@f
1013
	mov	cx, [ebx + gif.Image.info.Height]
1014
@@:
1015
	jecxz	.convrgb_norows
1016
.convrgb_convert_rows:
1017
	push	ecx
1018
	movzx	ecx, [ebx + gif.Image.info.Left]
1019
	cmp	ecx, [edx + Image.Width]
1020
	jb	@f
1021
	mov	ecx, [edx + Image.Width]
1022
@@:
1023
	push	ecx
1024
	call	.convrgb_prev
1025
	pop	ecx
1026
	sub	ecx, [edx + Image.Width]
1027
	neg	ecx
1028
	push	ecx edx
1029
	mov	edx, [esp+16]	; source data
1030
	cmp	cx, [ebx + gif.Image.info.Width]
1031
	jbe	@f
1032
	mov	cx, [ebx + gif.Image.info.Width]
1033
@@:
1034
	jecxz	.convrgb_norowsi
1035
.convrgb_rowsloop:
1036
	movzx	eax, byte [edx]
1037
	inc	edx
1038
	cmp	eax, [transparent_color]
1039
	jz	.convrgb_rows_transparent
1040
	shl	eax, 2
1041
	add	eax, [esp+20]	; source palette
1042
	mov	eax, [eax]
1043
	stosw
1044
	shr	eax, 16
1045
	stosb
1046
	call	.convrgb_lodsb
1047
	jmp	@f
1048
.convrgb_rows_transparent:
1049
	call	.convrgb_lodsb
1050
	stosw
1051
	shr	eax, 16
1052
	stosb
1053
@@:
1054
	loop	.convrgb_rowsloop
1055
.convrgb_norowsi:
1056
	pop	edx ecx
1057
	sub	cx, [ebx + gif.Image.info.Width]
1058
	jbe	@f
1059
	call	.convrgb_prev
1060
@@:
1061
	movzx	eax, [ebx + gif.Image.info.Width]
1062
	add	[esp+8], eax
1063
	pop	ecx
1064
	loop	.convrgb_convert_rows
1065
.convrgb_norows:
1066
	pop	ecx
1067
	sub	cx, [ebx + gif.Image.info.Height]
1068
	jbe	@f
1069
	imul	ecx, [edx + Image.Width]
1070
	call	.convrgb_prev
1071
@@:
1072
; free old image data
1073
	pop	esi esi ;esi
1074
	invoke	mem.free;, esi
1075
	retn
1076
.convrgb_nomem:
1077
	pop	esi esi
1078
	retn
1079
 
1080
.superimpose_on_rgb:
1081
; previous image is RGB, new image has transparent areas
1082
	xor	esi, esi
1083
	xchg	esi, [edx + Image.Data]
1084
	push	esi
1085
	mov	ebx, [_data]
1086
	push	[edx + Image.Palette]
1087
	mov	byte [edx + Image.Type], Image.bpp24
1088
	push	edx
1089
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1090
	push	eax
1091
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1092
	stdcall	img._.resize_data, edx, eax
1093
	pop	edx
1094
	test	eax, eax
1095
	jz	.rgb_nomem
1096
	push	esi
1097
	mov	edi, [edx + Image.Data]
1098
	mov	esi, [prev_img_data]
1099
	mov	ebx, [edx + Image.Extended]
1100
; first Top rows are copied from [prev_img_data] or filled with bgr
1101
	movzx	ecx, [ebx + gif.Image.info.Top]
1102
	cmp	ecx, [edx + Image.Height]
1103
	jb	@f
1104
	mov	ecx, [edx + Image.Height]
1105
@@:
1106
	push	ecx
1107
	lea	ecx, [ecx*3]
1108
	imul	ecx, [edx + Image.Width]
1109
	rep	movsb
1110
	pop	ecx
1111
; convert rows
1112
	sub	ecx, [edx + Image.Height]
1113
	neg	ecx
1114
	push	ecx
1115
	cmp	cx, [ebx + gif.Image.info.Height]
1116
	jbe	@f
1117
	mov	cx, [ebx + gif.Image.info.Height]
1118
@@:
1119
	jecxz	.rgb_norows
1120
.rgb_convert_rows:
1121
	push	ecx
1122
	movzx	ecx, [ebx + gif.Image.info.Left]
1123
	cmp	ecx, [edx + Image.Width]
1124
	jb	@f
1125
	mov	ecx, [edx + Image.Width]
1126
@@:
1127
	push	ecx
1128
	lea	ecx, [ecx*3]
1129
	rep	movsb
1130
	pop	ecx
1131
	sub	ecx, [edx + Image.Width]
1132
	neg	ecx
1133
	push	ecx edx
1134
	mov	edx, [esp+16]	; source data
1135
	cmp	cx, [ebx + gif.Image.info.Width]
1136
	jbe	@f
1137
	mov	cx, [ebx + gif.Image.info.Width]
1138
@@:
1139
	jecxz	.rgb_norowsi
1140
.rgb_rowsloop:
1141
	movzx	eax, byte [edx]
1142
	inc	edx
1143
	cmp	eax, [transparent_color]
1144
	jz	.rgb_rows_transparent
1145
	shl	eax, 2
1146
	add	eax, [esp+20]	; source palette
1147
	mov	eax, [eax]
1148
	stosw
1149
	shr	eax, 16
1150
	stosb
1151
	add	esi, 3
1152
	jmp	@f
1153
.rgb_rows_transparent:
1154
	movsb
1155
	movsb
1156
	movsb
1157
@@:
1158
	loop	.rgb_rowsloop
1159
.rgb_norowsi:
1160
	pop	edx ecx
1161
	sub	cx, [ebx + gif.Image.info.Width]
1162
	jbe	@f
1163
	lea	ecx, [ecx*3]
1164
	rep	movsb
1165
@@:
1166
	movzx	eax, [ebx + gif.Image.info.Width]
1167
	add	[esp+8], eax
1168
	pop	ecx
1169
	loop	.rgb_convert_rows
1170
.rgb_norows:
1171
	pop	ecx
1172
	sub	cx, [ebx + gif.Image.info.Height]
1173
	jbe	@f
1174
	imul	ecx, [edx + Image.Width]
1175
	lea	ecx, [ecx*3]
1176
	rep	movsb
1177
@@:
1178
; free old image data
1179
	pop	esi esi ;esi
1180
	invoke	mem.free;, esi
1181
	retn
1182
.rgb_nomem:
1183
	pop	esi esi
1184
	retn
1185
 
1186
.lodsb:
1187
	xor	eax, eax
1188
	test	esi, esi
1189
	jz	@f
1190
	lodsb
1191
@@:	retn
1192
 
1193
.rep_movsb_or_stosb:
1194
	test	esi, esi
1195
	jz	.rmos1
1196
	rep	movsb
1197
	jmp	.rmos2
1198
.rmos1:	xor	eax, eax	; background index in final palette is 0 in bgr mode
1199
	rep	stosb
1200
.rmos2:	retn
1201
 
1202
.convrgb_prev:
1203
	jecxz	.convrgb_noprev
1204
	test	esi, esi
1205
	jz	.convrgb_prev_bgr
1206
@@:
1207
	xor	eax, eax
1208
	lodsb
1209
	shl	eax, 2
1210
	add	eax, [prev_palette]
1211
	mov	eax, [eax]
1212
	stosw
1213
	shr	eax, 16
1214
	stosb
1215
	loop	@b
1216
	retn
1217
.convrgb_prev_bgr:
1218
@@:
1219
	mov	eax, [background_color]
1220
	stosw
1221
	shr	eax, 16
1222
	stosb
1223
	loop	@b
1224
.convrgb_noprev:
1225
	retn
1226
.convrgb_lodsb:
1227
	xor	eax, eax
1228
	test	esi, esi
1229
	jz	@f
1230
	lodsb
1231
	shl	eax, 2
1232
	add	eax, [prev_palette]
1233
	mov	eax, [eax]
1234
	retn
1235
@@:	mov	eax, [background_color]
1236
	retn
1237
 
1238
endp
1239
 
1240
;;================================================================================================;;
1241
proc img.decode.gif._.dispose ;///////////////////////////////////////////////////////////////////;;
1242
;;------------------------------------------------------------------------------------------------;;
1243
;? --- TBD ---                                                                                    ;;
1244
;;------------------------------------------------------------------------------------------------;;
1245
;> edx = image data                                                                               ;;
1246
;;------------------------------------------------------------------------------------------------;;
1247
;< --- TBD ---                                                                                    ;;
1248
;;================================================================================================;;
1249
	mov	ebx, [edx + Image.Extended]
1250
	mov	al, [ebx + gif.Image.gce.Packed]
1251
	shr	al, 2
1252
	and	al, 7
1253
	cmp	al, 2
1254
	jz	.background
1255
	cmp	al, 3
1256
	jz	.previous
1257
; don't dispose - set prev_img and related vars to current image
1258
	mov	eax, [edx + Image.Data]
1259
	mov	[prev_img_data], eax
1260
	cmp	[edx + Image.Type], Image.bpp8
1261
	jnz	@f
1262
	mov	eax, [max_color]
1263
	inc	eax
1264
	mov	[prev_num_colors], eax
1265
	mov	eax, [edx + Image.Palette]
1266
	mov	[prev_palette], eax
1267
	retn
1268
@@:
1269
	or	[prev_num_colors], -1
1270
	and	[prev_palette], 0
1271
.previous:
1272
	retn
1273
.background:
1274
	cmp	[prev_img_data], 0
1275
	jz	.bgr_full
1276
	mov	ebx, [main_img]
1277
	mov	eax, [edx + Image.Extended]
1278
	call	img.decode.gif._.is_logical_screen
1279
	jnz	@f
1280
.bgr_full:
1281
	xor	eax, eax
1282
	mov	[prev_img_data], eax
1283
	inc	eax
1284
	mov	[prev_num_colors], eax
1285
	lea	eax, [background_color]
1286
	mov	[prev_palette], eax
1287
	retn
1288
@@:
1289
	cmp	[prev_num_colors], 0x100
1290
	ja	.rgb
1291
	mov	eax, [background_color]
1292
	mov	edi, [prev_palette]
1293
	mov	ecx, [prev_num_colors]
1294
	repnz	scasd
1295
	jz	.palette_ok
1296
	cmp	[prev_num_colors], 0x100
1297
	jz	.convert_rgb
1298
	push	1
1299
	pop	eax
1300
	stdcall	img.decode.gif._.alloc_aux_img
1301
	test	eax, eax
1302
	jz	.previous
1303
	mov	ecx, [prev_num_colors]
1304
	mov	esi, [prev_palette]
1305
	call	img.decode.gif._.alloc_aux_palette
1306
	test	eax, eax
1307
	jz	.previous
1308
	mov	[prev_palette], eax
1309
	mov	eax, [background_color]
1310
	stosd
1311
	mov	eax, [prev_num_colors]	; eax = index of background color
1312
	inc	[prev_num_colors]
1313
	jmp	.bpp8_common
1314
.palette_ok:
1315
	push	1
1316
	pop	eax
1317
	stdcall	img.decode.gif._.alloc_aux_img
1318
	test	eax, eax
1319
	jz	.previous
1320
	sub	edi, [prev_palette]
1321
	shr	edi, 2
1322
	lea	eax, [edi-1]	; eax = index of background color
1323
.bpp8_common:
1324
	push	eax
1325
	mov	ebx, [_data]
1326
	mov	esi, [prev_img_data]
1327
	mov	edi, [aux_img_data]
1328
	mov	[prev_img_data], edi
1329
	cmp	esi, edi
1330
	jz	@f
1331
	movzx	ecx, [ebx + gif.Header.lsd.ScreenWidth]
1332
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1333
	imul	ecx, eax
1334
	push	edi
1335
	rep	movsb
1336
	pop	edi
1337
@@:
1338
	movzx	esi, [ebx + gif.Header.lsd.ScreenHeight]
1339
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1340
	mov	edx, [edx + Image.Extended]
1341
	movzx	ecx, [edx + gif.Image.info.Top]
1342
	sub	esi, ecx
1343
	jbe	.bpp8_ret
1344
	imul	ecx, eax
1345
	add	edi, ecx
1346
	cmp	si, [edx + gif.Image.info.Height]
1347
	jb	@f
1348
	mov	si, [edx + gif.Image.info.Height]
1349
@@:
1350
	movzx	ecx, [edx + gif.Image.info.Left]
1351
	sub	eax, ecx
1352
	jbe	.bpp8_ret
1353
	add	edi, ecx
1354
	cmp	ax, [edx + gif.Image.info.Width]
1355
	jb	@f
1356
	mov	ax, [edx + gif.Image.info.Width]
1357
@@:
1358
	xchg	eax, ecx
1359
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1360
	sub	edx, ecx
1361
	pop	eax
1362
@@:
1363
	push	ecx
1364
	rep	stosb
1365
	pop	ecx
1366
	add	edi, edx
1367
	dec	esi
1368
	jnz	@b
1369
	push	eax
1370
.bpp8_ret:
1371
	pop	eax
1372
	retn
1373
.convert_rgb:
1374
	push	3
1375
	pop	eax
1376
	stdcall	img.decode.gif._.alloc_aux_img
1377
	test	eax, eax
1378
	jz	.previous
1379
	or	[prev_num_colors], -1
1380
	mov	ebx, [_data]
1381
	mov	esi, [prev_img_data]
1382
	mov	edi, [aux_img_data]
1383
	mov	[prev_img_data], edi
1384
	movzx	ecx, [ebx + gif.Header.lsd.ScreenWidth]
1385
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1386
	imul	ecx, eax
1387
	push	edx
1388
	xor	edx, edx
1389
	xchg	edx, [prev_palette]
1390
	add	edi, ecx
1391
	add	esi, ecx
1392
	add	edi, ecx
1393
	add	edi, ecx
1394
@@:
1395
	dec	esi
1396
	movzx	eax, byte [esi]
1397
	mov	eax, [eax*4+edx]
1398
	sub	edi, 3
1399
	mov	[edi], ax
1400
	shr	eax, 16
1401
	mov	[edi+2], al
1402
	loop	@b
1403
	pop	edx
1404
	movzx	esi, [ebx + gif.Header.lsd.ScreenHeight]
1405
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1406
	mov	edx, [edx + Image.Extended]
1407
	movzx	ecx, [edx + gif.Image.info.Top]
1408
	sub	esi, ecx
1409
	jbe	.convert_rgb_ret
1410
	imul	ecx, eax
1411
	lea	ecx, [ecx*3]
1412
	add	edi, ecx
1413
	cmp	si, [edx + gif.Image.info.Height]
1414
	jb	@f
1415
	mov	si, [edx + gif.Image.info.Height]
1416
@@:
1417
	movzx	ecx, [edx + gif.Image.info.Left]
1418
	sub	eax, ecx
1419
	jbe	.convert_rgb_ret
1420
	lea	ecx, [ecx*3]
1421
	add	edi, ecx
1422
	cmp	ax, [edx + gif.Image.info.Width]
1423
	jb	@f
1424
	mov	ax, [edx + gif.Image.info.Width]
1425
@@:
1426
	xchg	eax, ecx
1427
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1428
	sub	edx, ecx
1429
	mov	eax, [background_color]
1430
	lea	edx, [edx*3]
1431
.convert_rgb_loop:
1432
	push	ecx
1433
@@:
1434
	stosw
1435
	shr	eax, 16
1436
	stosb
1437
	loop	@b
1438
	pop	ecx
1439
	add	edi, edx
1440
	dec	esi
1441
	jnz	.convert_rgb_loop
1442
.convert_rgb_ret:
1443
	retn
1444
.rgb:
1445
	push	3
1446
	pop	eax
1447
	stdcall	img.decode.gif._.alloc_aux_img
1448
	test	eax, eax
1449
	jz	.previous
1450
	or	[prev_num_colors], -1
1451
	and	[prev_palette], 0
1452
	mov	ebx, [_data]
1453
	mov	esi, [prev_img_data]
1454
	mov	edi, [aux_img_data]
1455
	mov	[prev_img_data], edi
1456
	cmp	esi, edi
1457
	jz	@f
1458
	movzx	ecx, [ebx + gif.Header.lsd.ScreenHeight]
1459
	push	ecx
1460
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1461
	imul	ecx, eax
1462
	lea	ecx, [ecx*3]
1463
	push	edi
1464
	rep	movsb
1465
	pop	edi
1466
	pop	esi
1467
	mov	edx, [edx + Image.Extended]
1468
	movzx	ecx, [edx + gif.Image.info.Top]
1469
	sub	esi, ecx
1470
	jbe	.rgb_ret
1471
	imul	ecx, eax
1472
	lea	ecx, [ecx*3]
1473
	add	edi, ecx
1474
	cmp	si, [edx + gif.Image.info.Height]
1475
	jb	@f
1476
	mov	si, [edx + gif.Image.info.Height]
1477
@@:
1478
	movzx	ecx, [edx + gif.Image.info.Left]
1479
	sub	eax, ecx
1480
	jbe	.rgb_ret
1481
	lea	ecx, [ecx*3]
1482
	add	edi, ecx
1483
	cmp	ax, [edx + gif.Image.info.Width]
1484
	jb	@f
1485
	mov	ax, [edx + gif.Image.info.Width]
1486
@@:
1487
	xchg	eax, ecx
1488
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1489
	sub	edx, ecx
1490
	mov	eax, [background_color]
1491
	lea	edx, [edx*3]
1492
.rgb_loop:
1493
	push	ecx
1494
@@:
1495
	stosw
1496
	shr	eax, 16
1497
	stosb
1498
	loop	@b
1499
	pop	ecx
1500
	add	edi, edx
1501
	dec	esi
1502
	jnz	.rgb_loop
1503
.rgb_ret:
1504
	retn
1505
 
1506
endp
1507
 
1508
;;================================================================================================;;
1509
proc img.decode.gif._.alloc_aux_img ;/////////////////////////////////////////////////////////////;;
1510
;;------------------------------------------------------------------------------------------------;;
1511
;? Allocate auxiliary memory for previous image                                                   ;;
1512
;;------------------------------------------------------------------------------------------------;;
1513
;> eax = image type: 1 = bpp8, 3 = bpp24                                                          ;;
1514
;;------------------------------------------------------------------------------------------------;;
1515
;< eax = [aux_img_data]                                                                           ;;
1516
;;================================================================================================;;
1517
	cmp	[aux_img_type], eax
1518
	jae	@f
1519
	push	edx eax
1520
	movzx	ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
1521
	mul	ecx
1522
	movzx	ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
1523
	mul	ecx
1524
	invoke	mem.realloc, [aux_img_data], eax
1525
	pop	ecx edx
1526
	test	eax, eax
1527
	jz	@f
1528
	mov	[aux_img_type], ecx
1529
	mov	[aux_img_data], eax
1530
@@:	retn
1531
 
1532
endp
1533
 
1534
;;================================================================================================;;
1535
proc img.decode.gif._.alloc_aux_palette ;/////////////////////////////////////////////////////////;;
1536
;;------------------------------------------------------------------------------------------------;;
1537
;? Allocate and fill aux_palette                                                                  ;;
1538
;;------------------------------------------------------------------------------------------------;;
1539
;> esi -> palette, ecx = palette size                                                             ;;
1540
;;------------------------------------------------------------------------------------------------;;
1541
;< [aux_palette] set                                                                              ;;
1542
;;================================================================================================;;
1543
	mov	eax, [aux_palette]
1544
	test	eax, eax
1545
	jnz	@f
1546
	push	edx ecx
1547
	invoke	mem.alloc, 0x400
1548
	pop	ecx edx
1549
	test	eax, eax
1550
	jz	.ret
1551
	mov	[aux_palette], eax
1552
@@:
1553
	mov	edi, eax
1554
	rep	movsd
1555
.ret:
1556
	retn
1557
 
1558
endp
1559
 
1560
restore main_img
1561
restore transparent_color
1562
restore background_color
1563
restore prev_num_colors
1564
restore prev_palette
1565
restore max_color
1566
restore prev_img_data
1567
restore _data
1568
restore aux_img_data
1569
restore aux_img_type
1570
restore aux_palette
1571
 
1572
;;================================================================================================;;
717 mikedld 1573
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1574
;;================================================================================================;;
1575
;! Below is private data you should never use directly from your code                             ;;
1576
;;================================================================================================;;
1577
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1578
;;================================================================================================;;
1579
 
1580
 
1581
;