Subversion Repositories Kolibri OS

Rev

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