Subversion Repositories Kolibri OS

Rev

Rev 1121 | Rev 8341 | 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
1118 diamond 116
; child saved ebp, return address, 3 saved registers, 15 local variables
117
img.decode.gif._length_child equ _length + 4 + 4 + 4*3 + 4*15
1079 diamond 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
2733 dunkaist 212
	mov	[eax + Image.Type], Image.bpp8i
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]
1121 diamond 293
	cmp	[edx + Image.Delay], 0
1079 diamond 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
2733 dunkaist 309
	cmp	[edx + Image.Type], Image.bpp8i
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
 
701
	cmp	edi, [row_end]
702
	jb	.norowend
703
	mov	eax, [width]
704
	push	eax
705
	sub	edi, eax
706
	add	eax, eax
707
	cmp	[pass], 3
708
	je	@f
709
	add	eax, eax
710
	cmp	[pass], 2
711
	je	@f
712
	add	eax, eax
713
    @@: add	edi, eax
714
	pop	eax
715
	cmp	edi, [img_end]
716
	jb	.nextrow
717
	mov	edi, [img_start]
718
	inc	[pass]
1121 diamond 719
	cmp	[pass], 4
720
	je	.done
717 mikedld 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:
1121 diamond 737
	cmp	edi, [img_end]
738
	jz	.done
717 mikedld 739
	loop	.loop2
740
	pop	edx eax esi
741
	retn
742
 
1079 diamond 743
  .done:
744
	lea	esp, [esp+(ecx-1)*2]
745
	pop	edx eax esi eax
746
	jmp	img.decode.gif._.process_image.exit
747
 
717 mikedld 748
endp
749
 
1079 diamond 750
;;================================================================================================;;
751
proc img.decode.gif._.is_logical_screen ;/////////////////////////////////////////////////////////;;
752
;;------------------------------------------------------------------------------------------------;;
753
;? Determines whether GIF image occupies the whole logical screen                                 ;;
754
;;------------------------------------------------------------------------------------------------;;
755
;> eax = extended image data                                                                      ;;
756
;> ebx = main image                                                                               ;;
757
;;------------------------------------------------------------------------------------------------;;
758
;< ZF set <=> image area equals logical screen                                                    ;;
759
;;================================================================================================;;
760
	mov	ebx, [ebx + Image.Extended]
761
	cmp	[eax + gif.Image.info.Left], 0
762
	jnz	@f
763
	cmp	[eax + gif.Image.info.Top], 0
764
	jnz	@f
765
	mov	cx, [eax + gif.Image.info.Width]
766
	cmp	cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
767
	jnz	@f
768
	mov	cx, [eax + gif.Image.info.Height]
769
	cmp	cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
770
@@:	retn
771
endp
717 mikedld 772
 
1079 diamond 773
main_img equ img.decode.gif.main_img
774
transparent_color equ img.decode.gif.transparent_color
775
background_color equ img.decode.gif.background_color
776
prev_num_colors equ img.decode.gif.prev_num_colors
777
prev_palette equ img.decode.gif.prev_palette
778
max_color equ img.decode.gif.max_color
779
prev_img_data equ img.decode.gif.prev_img_data
780
_data equ img.decode.gif._data
781
aux_img_data equ img.decode.gif.aux_img_data
782
aux_img_type equ img.decode.gif.aux_img_type
783
aux_palette equ img.decode.gif.aux_palette
784
 
717 mikedld 785
;;================================================================================================;;
1079 diamond 786
proc img.decode.gif._.superimpose ;///////////////////////////////////////////////////////////////;;
787
;;------------------------------------------------------------------------------------------------;;
788
;? --- TBD ---                                                                                    ;;
789
;;------------------------------------------------------------------------------------------------;;
790
;> edx = image data                                                                               ;;
791
;;------------------------------------------------------------------------------------------------;;
792
;< --- TBD ---                                                                                    ;;
793
;;================================================================================================;;
794
	mov	ebx, [main_img]
795
	mov	eax, [edx + Image.Extended]
796
	or	[transparent_color], -1		; no transparent color
797
	test	byte [eax + gif.Image.gce.Packed], 1
798
	jz	@f
799
	movzx	ecx, byte [eax + gif.Image.gce.ColorIndex]
800
	mov	[transparent_color], ecx
801
	cmp	edx, ebx
802
	jnz	.has_transparency
803
	shl	ecx, 2
804
	add	ecx, [edx + Image.Palette]
1102 diamond 805
	push	eax
806
	mov	eax, [img.decode.gif.options_bgr]
807
	mov	dword [background_color], eax
808
	mov	dword [ecx], eax
809
	pop	eax
1079 diamond 810
@@:
811
	call	img.decode.gif._.is_logical_screen
812
	jnz	.has_transparency
813
; image is not transparent, so keep it as is
814
	retn
815
 
816
.has_transparency:
817
; image has transparent areas, we must superimpose it on the previous
818
	mov	ecx, [prev_num_colors]
819
	cmp	ecx, 0x100
820
	ja	.superimpose_on_rgb
821
; create common palette
822
	sub	esp, 3FCh
823
	push	eax
824
	mov	edi, esp
825
	push	ecx
826
	mov	esi, [prev_palette]
827
	rep	movsd
828
	pop	ecx
829
	mov	esi, [edx + Image.Palette]
830
	xor	ebx, ebx
831
	mov	edi, esp
832
	sub	esp, 100h
833
.create_palette_loop:
834
	push	ecx
835
	lodsd
836
	cmp	ebx, [transparent_color]
837
	jz	.nochange
838
	cmp	ebx, ecx
839
	jae	@f
840
	cmp	eax, [edi+ebx*4]
841
	jz	.nochange
842
@@:
843
	push	edi
844
	repnz	scasd
845
	pop	edi
846
	jnz	.increase_palette
847
	sub	ecx, [esp]
848
	not	ecx	; cl = index of new color in current palette
849
	jmp	.palette_common
850
.increase_palette:
851
	mov	ecx, [esp]
852
	test	ch, ch
853
	jnz	.output_to_rgb
854
	inc	dword [esp]
855
	mov	[edi+ecx*4], eax
856
	jmp	.palette_common
857
.nochange:
858
	mov	ecx, ebx
859
.palette_common:
860
	mov	[ebx+esp+4], cl
861
	pop	ecx
862
	inc	ebx
863
	cmp	ebx, [max_color]
864
	jbe	.create_palette_loop
865
	mov	[max_color], ecx
866
; if image occupies only part of logical screen, allocate memory for full logical screen
867
	mov	ebx, [main_img]
868
	mov	eax, [edx + Image.Extended]
869
	mov	esi, [edx + Image.Data]
870
	call	img.decode.gif._.is_logical_screen
871
	jz	@f
872
	and	[edx + Image.Data], 0
873
	push	edx
874
	movzx	eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
875
	push	eax
876
	movzx	eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
877
	stdcall	img._.resize_data, edx, eax
878
	pop	edx
879
	test	eax, eax
880
	jz	.palette_nomem
881
@@:
882
; copy final palette to Image.Palette
883
	push	esi esi
884
	mov	esi, edi
885
	mov	edi, [edx + Image.Palette]
886
	mov	ecx, [max_color]
887
	dec	[max_color]
888
	rep	movsd
889
	mov	esi, [prev_img_data]
890
	mov	edi, [edx + Image.Data]
891
; do superimpose, [esp] -> source data, esi -> prev image data
892
;   (NULL if previous image is filled with background color), esp+8 -> correspondence between
893
;   used palette and final palette, edi -> destination data
894
	mov	ebx, [edx + Image.Extended]
895
; first Top rows are copied from [prev_img_data] or filled with bgr
896
	movzx	ecx, [ebx + gif.Image.info.Top]
897
	cmp	ecx, [edx + Image.Height]
898
	jb	@f
899
	mov	ecx, [edx + Image.Height]
900
@@:
901
	push	ecx
902
	imul	ecx, [edx + Image.Width]
903
	call	.rep_movsb_or_stosb
904
	pop	ecx
905
; convert rows
906
	sub	ecx, [edx + Image.Height]
907
	neg	ecx
908
	push	ecx
909
	cmp	cx, [ebx + gif.Image.info.Height]
910
	jbe	@f
911
	mov	cx, [ebx + gif.Image.info.Height]
912
@@:
913
	jecxz	.norows
914
.convert_rows:
915
	push	ecx
916
	movzx	ecx, [ebx + gif.Image.info.Left]
917
	cmp	ecx, [edx + Image.Width]
918
	jb	@f
919
	mov	ecx, [edx + Image.Width]
920
@@:
921
	push	ecx
922
	call	.rep_movsb_or_stosb
923
	pop	ecx
924
	sub	ecx, [edx + Image.Width]
925
	neg	ecx
926
	push	ecx edx
927
	mov	edx, [esp+16]	; source data
928
	cmp	cx, [ebx + gif.Image.info.Width]
929
	jbe	@f
930
	mov	cx, [ebx + gif.Image.info.Width]
931
@@:
932
	jecxz	.norowsi
933
.rowsloop:
934
	movzx	eax, byte [edx]
935
	inc	edx
936
	cmp	eax, [transparent_color]
937
	jz	.rows_transparent
938
	mov	al, [eax+esp+24]
939
	stosb
940
	call	.lodsb
941
	jmp	@f
942
.rows_transparent:
943
	call	.lodsb
944
	stosb
945
@@:
946
	loop	.rowsloop
947
.norowsi:
948
	pop	edx ecx
949
	sub	cx, [ebx + gif.Image.info.Width]
950
	jbe	@f
951
	call	.rep_movsb_or_stosb
952
@@:
953
	movzx	eax, [ebx + gif.Image.info.Width]
954
	add	[esp+8], eax
955
	pop	ecx
956
	loop	.convert_rows
957
.norows:
958
	pop	ecx
959
	sub	cx, [ebx + gif.Image.info.Height]
960
	jbe	@f
961
	imul	ecx, [edx + Image.Width]
962
	call	.rep_movsb_or_stosb
963
@@:
964
; free old image data if we have allocated new copy
965
	pop	esi esi
966
	cmp	esi, [edx + Image.Data]
967
	jz	@f
968
	invoke	mem.free, esi
969
@@:
970
; cleanup stack and return
971
	add	esp, 500h
972
	retn
973
.palette_nomem:
974
	mov	[edx + Image.Data], esi
975
	jmp	@b
976
 
977
.output_to_rgb:
978
	pop	ecx
979
	add	esp, 500h
980
; compose two palette-based images to one RGB image
981
	xor	esi, esi
982
	xchg	esi, [edx + Image.Data]
983
	push	esi
984
	mov	ebx, [_data]
985
	push	[edx + Image.Palette]
986
	mov	byte [edx + Image.Type], Image.bpp24
987
	push	edx
988
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
989
	push	eax
990
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
991
	stdcall	img._.resize_data, edx, eax
992
	pop	edx
993
	test	eax, eax
994
	jz	.convrgb_nomem
995
	push	esi
996
	mov	edi, [edx + Image.Data]
997
	mov	esi, [prev_img_data]
998
	mov	ebx, [edx + Image.Extended]
999
; first Top rows are copied from [prev_img_data] or filled with bgr
1000
	movzx	ecx, [ebx + gif.Image.info.Top]
1001
	cmp	ecx, [edx + Image.Height]
1002
	jb	@f
1003
	mov	ecx, [edx + Image.Height]
1004
@@:
1005
	push	ecx
1006
	imul	ecx, [edx + Image.Width]
1007
	call	.convrgb_prev
1008
	pop	ecx
1009
; convert rows
1010
	sub	ecx, [edx + Image.Height]
1011
	neg	ecx
1012
	push	ecx
1013
	cmp	cx, [ebx + gif.Image.info.Height]
1014
	jbe	@f
1015
	mov	cx, [ebx + gif.Image.info.Height]
1016
@@:
1017
	jecxz	.convrgb_norows
1018
.convrgb_convert_rows:
1019
	push	ecx
1020
	movzx	ecx, [ebx + gif.Image.info.Left]
1021
	cmp	ecx, [edx + Image.Width]
1022
	jb	@f
1023
	mov	ecx, [edx + Image.Width]
1024
@@:
1025
	push	ecx
1026
	call	.convrgb_prev
1027
	pop	ecx
1028
	sub	ecx, [edx + Image.Width]
1029
	neg	ecx
1030
	push	ecx edx
1031
	mov	edx, [esp+16]	; source data
1032
	cmp	cx, [ebx + gif.Image.info.Width]
1033
	jbe	@f
1034
	mov	cx, [ebx + gif.Image.info.Width]
1035
@@:
1036
	jecxz	.convrgb_norowsi
1037
.convrgb_rowsloop:
1038
	movzx	eax, byte [edx]
1039
	inc	edx
1040
	cmp	eax, [transparent_color]
1041
	jz	.convrgb_rows_transparent
1042
	shl	eax, 2
1043
	add	eax, [esp+20]	; source palette
1044
	mov	eax, [eax]
1045
	stosw
1046
	shr	eax, 16
1047
	stosb
1048
	call	.convrgb_lodsb
1049
	jmp	@f
1050
.convrgb_rows_transparent:
1051
	call	.convrgb_lodsb
1052
	stosw
1053
	shr	eax, 16
1054
	stosb
1055
@@:
1056
	loop	.convrgb_rowsloop
1057
.convrgb_norowsi:
1058
	pop	edx ecx
1059
	sub	cx, [ebx + gif.Image.info.Width]
1060
	jbe	@f
1061
	call	.convrgb_prev
1062
@@:
1063
	movzx	eax, [ebx + gif.Image.info.Width]
1064
	add	[esp+8], eax
1065
	pop	ecx
1066
	loop	.convrgb_convert_rows
1067
.convrgb_norows:
1068
	pop	ecx
1069
	sub	cx, [ebx + gif.Image.info.Height]
1070
	jbe	@f
1071
	imul	ecx, [edx + Image.Width]
1072
	call	.convrgb_prev
1073
@@:
1074
; free old image data
1075
	pop	esi esi ;esi
1076
	invoke	mem.free;, esi
1077
	retn
1078
.convrgb_nomem:
1079
	pop	esi esi
1080
	retn
1081
 
1082
.superimpose_on_rgb:
1083
; previous image is RGB, new image has transparent areas
1084
	xor	esi, esi
1085
	xchg	esi, [edx + Image.Data]
1086
	push	esi
1087
	mov	ebx, [_data]
1088
	push	[edx + Image.Palette]
1089
	mov	byte [edx + Image.Type], Image.bpp24
1090
	push	edx
1091
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1092
	push	eax
1093
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1094
	stdcall	img._.resize_data, edx, eax
1095
	pop	edx
1096
	test	eax, eax
1097
	jz	.rgb_nomem
1098
	push	esi
1099
	mov	edi, [edx + Image.Data]
1100
	mov	esi, [prev_img_data]
1101
	mov	ebx, [edx + Image.Extended]
1102
; first Top rows are copied from [prev_img_data] or filled with bgr
1103
	movzx	ecx, [ebx + gif.Image.info.Top]
1104
	cmp	ecx, [edx + Image.Height]
1105
	jb	@f
1106
	mov	ecx, [edx + Image.Height]
1107
@@:
1108
	push	ecx
1109
	lea	ecx, [ecx*3]
1110
	imul	ecx, [edx + Image.Width]
1111
	rep	movsb
1112
	pop	ecx
1113
; convert rows
1114
	sub	ecx, [edx + Image.Height]
1115
	neg	ecx
1116
	push	ecx
1117
	cmp	cx, [ebx + gif.Image.info.Height]
1118
	jbe	@f
1119
	mov	cx, [ebx + gif.Image.info.Height]
1120
@@:
1121
	jecxz	.rgb_norows
1122
.rgb_convert_rows:
1123
	push	ecx
1124
	movzx	ecx, [ebx + gif.Image.info.Left]
1125
	cmp	ecx, [edx + Image.Width]
1126
	jb	@f
1127
	mov	ecx, [edx + Image.Width]
1128
@@:
1129
	push	ecx
1130
	lea	ecx, [ecx*3]
1131
	rep	movsb
1132
	pop	ecx
1133
	sub	ecx, [edx + Image.Width]
1134
	neg	ecx
1135
	push	ecx edx
1136
	mov	edx, [esp+16]	; source data
1137
	cmp	cx, [ebx + gif.Image.info.Width]
1138
	jbe	@f
1139
	mov	cx, [ebx + gif.Image.info.Width]
1140
@@:
1141
	jecxz	.rgb_norowsi
1142
.rgb_rowsloop:
1143
	movzx	eax, byte [edx]
1144
	inc	edx
1145
	cmp	eax, [transparent_color]
1146
	jz	.rgb_rows_transparent
1147
	shl	eax, 2
1148
	add	eax, [esp+20]	; source palette
1149
	mov	eax, [eax]
1150
	stosw
1151
	shr	eax, 16
1152
	stosb
1153
	add	esi, 3
1154
	jmp	@f
1155
.rgb_rows_transparent:
1156
	movsb
1157
	movsb
1158
	movsb
1159
@@:
1160
	loop	.rgb_rowsloop
1161
.rgb_norowsi:
1162
	pop	edx ecx
1163
	sub	cx, [ebx + gif.Image.info.Width]
1164
	jbe	@f
1165
	lea	ecx, [ecx*3]
1166
	rep	movsb
1167
@@:
1168
	movzx	eax, [ebx + gif.Image.info.Width]
1169
	add	[esp+8], eax
1170
	pop	ecx
1171
	loop	.rgb_convert_rows
1172
.rgb_norows:
1173
	pop	ecx
1174
	sub	cx, [ebx + gif.Image.info.Height]
1175
	jbe	@f
1176
	imul	ecx, [edx + Image.Width]
1177
	lea	ecx, [ecx*3]
1178
	rep	movsb
1179
@@:
1180
; free old image data
1181
	pop	esi esi ;esi
1182
	invoke	mem.free;, esi
1183
	retn
1184
.rgb_nomem:
1185
	pop	esi esi
1186
	retn
1187
 
1188
.lodsb:
1189
	xor	eax, eax
1190
	test	esi, esi
1191
	jz	@f
1192
	lodsb
1193
@@:	retn
1194
 
1195
.rep_movsb_or_stosb:
1196
	test	esi, esi
1197
	jz	.rmos1
1198
	rep	movsb
1199
	jmp	.rmos2
1200
.rmos1:	xor	eax, eax	; background index in final palette is 0 in bgr mode
1201
	rep	stosb
1202
.rmos2:	retn
1203
 
1204
.convrgb_prev:
1205
	jecxz	.convrgb_noprev
1206
	test	esi, esi
1207
	jz	.convrgb_prev_bgr
1208
@@:
1209
	xor	eax, eax
1210
	lodsb
1211
	shl	eax, 2
1212
	add	eax, [prev_palette]
1213
	mov	eax, [eax]
1214
	stosw
1215
	shr	eax, 16
1216
	stosb
1217
	loop	@b
1218
	retn
1219
.convrgb_prev_bgr:
1220
@@:
1221
	mov	eax, [background_color]
1222
	stosw
1223
	shr	eax, 16
1224
	stosb
1225
	loop	@b
1226
.convrgb_noprev:
1227
	retn
1228
.convrgb_lodsb:
1229
	xor	eax, eax
1230
	test	esi, esi
1231
	jz	@f
1232
	lodsb
1233
	shl	eax, 2
1234
	add	eax, [prev_palette]
1235
	mov	eax, [eax]
1236
	retn
1237
@@:	mov	eax, [background_color]
1238
	retn
1239
 
1240
endp
1241
 
1242
;;================================================================================================;;
1243
proc img.decode.gif._.dispose ;///////////////////////////////////////////////////////////////////;;
1244
;;------------------------------------------------------------------------------------------------;;
1245
;? --- TBD ---                                                                                    ;;
1246
;;------------------------------------------------------------------------------------------------;;
1247
;> edx = image data                                                                               ;;
1248
;;------------------------------------------------------------------------------------------------;;
1249
;< --- TBD ---                                                                                    ;;
1250
;;================================================================================================;;
1251
	mov	ebx, [edx + Image.Extended]
1252
	mov	al, [ebx + gif.Image.gce.Packed]
1253
	shr	al, 2
1254
	and	al, 7
1255
	cmp	al, 2
1256
	jz	.background
1257
	cmp	al, 3
1258
	jz	.previous
1259
; don't dispose - set prev_img and related vars to current image
1260
	mov	eax, [edx + Image.Data]
1261
	mov	[prev_img_data], eax
2733 dunkaist 1262
	cmp	[edx + Image.Type], Image.bpp8i
1079 diamond 1263
	jnz	@f
1264
	mov	eax, [max_color]
1265
	inc	eax
1266
	mov	[prev_num_colors], eax
1267
	mov	eax, [edx + Image.Palette]
1268
	mov	[prev_palette], eax
1269
	retn
1270
@@:
1271
	or	[prev_num_colors], -1
1272
	and	[prev_palette], 0
1273
.previous:
1274
	retn
1275
.background:
1276
	cmp	[prev_img_data], 0
1277
	jz	.bgr_full
1278
	mov	ebx, [main_img]
1279
	mov	eax, [edx + Image.Extended]
1280
	call	img.decode.gif._.is_logical_screen
1281
	jnz	@f
1282
.bgr_full:
1283
	xor	eax, eax
1284
	mov	[prev_img_data], eax
1285
	inc	eax
1286
	mov	[prev_num_colors], eax
1287
	lea	eax, [background_color]
1288
	mov	[prev_palette], eax
1289
	retn
1290
@@:
1291
	cmp	[prev_num_colors], 0x100
1292
	ja	.rgb
1293
	mov	eax, [background_color]
1294
	mov	edi, [prev_palette]
1295
	mov	ecx, [prev_num_colors]
1296
	repnz	scasd
1297
	jz	.palette_ok
1298
	cmp	[prev_num_colors], 0x100
1299
	jz	.convert_rgb
1300
	push	1
1301
	pop	eax
1302
	stdcall	img.decode.gif._.alloc_aux_img
1303
	test	eax, eax
1304
	jz	.previous
1305
	mov	ecx, [prev_num_colors]
1306
	mov	esi, [prev_palette]
1307
	call	img.decode.gif._.alloc_aux_palette
1308
	test	eax, eax
1309
	jz	.previous
1310
	mov	[prev_palette], eax
1311
	mov	eax, [background_color]
1312
	stosd
1313
	mov	eax, [prev_num_colors]	; eax = index of background color
1314
	inc	[prev_num_colors]
1315
	jmp	.bpp8_common
1316
.palette_ok:
1317
	push	1
1318
	pop	eax
1319
	stdcall	img.decode.gif._.alloc_aux_img
1320
	test	eax, eax
1321
	jz	.previous
1322
	sub	edi, [prev_palette]
1323
	shr	edi, 2
1324
	lea	eax, [edi-1]	; eax = index of background color
1325
.bpp8_common:
1326
	push	eax
1327
	mov	ebx, [_data]
1328
	mov	esi, [prev_img_data]
1329
	mov	edi, [aux_img_data]
1330
	mov	[prev_img_data], edi
1331
	cmp	esi, edi
1332
	jz	@f
1333
	movzx	ecx, [ebx + gif.Header.lsd.ScreenWidth]
1334
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1335
	imul	ecx, eax
1336
	push	edi
1337
	rep	movsb
1338
	pop	edi
1339
@@:
1340
	movzx	esi, [ebx + gif.Header.lsd.ScreenHeight]
1341
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1342
	mov	edx, [edx + Image.Extended]
1343
	movzx	ecx, [edx + gif.Image.info.Top]
1344
	sub	esi, ecx
1345
	jbe	.bpp8_ret
1346
	imul	ecx, eax
1347
	add	edi, ecx
1348
	cmp	si, [edx + gif.Image.info.Height]
1349
	jb	@f
1350
	mov	si, [edx + gif.Image.info.Height]
1351
@@:
1352
	movzx	ecx, [edx + gif.Image.info.Left]
1353
	sub	eax, ecx
1354
	jbe	.bpp8_ret
1355
	add	edi, ecx
1356
	cmp	ax, [edx + gif.Image.info.Width]
1357
	jb	@f
1358
	mov	ax, [edx + gif.Image.info.Width]
1359
@@:
1360
	xchg	eax, ecx
1361
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1362
	sub	edx, ecx
1363
	pop	eax
1364
@@:
1365
	push	ecx
1366
	rep	stosb
1367
	pop	ecx
1368
	add	edi, edx
1369
	dec	esi
1370
	jnz	@b
1371
	push	eax
1372
.bpp8_ret:
1373
	pop	eax
1374
	retn
1375
.convert_rgb:
1376
	push	3
1377
	pop	eax
1378
	stdcall	img.decode.gif._.alloc_aux_img
1379
	test	eax, eax
1380
	jz	.previous
1381
	or	[prev_num_colors], -1
1382
	mov	ebx, [_data]
1383
	mov	esi, [prev_img_data]
1384
	mov	edi, [aux_img_data]
1385
	mov	[prev_img_data], edi
1386
	movzx	ecx, [ebx + gif.Header.lsd.ScreenWidth]
1387
	movzx	eax, [ebx + gif.Header.lsd.ScreenHeight]
1388
	imul	ecx, eax
1389
	push	edx
1390
	xor	edx, edx
1391
	xchg	edx, [prev_palette]
1392
	add	edi, ecx
1393
	add	esi, ecx
1394
	add	edi, ecx
1395
	add	edi, ecx
1396
@@:
1397
	dec	esi
1398
	movzx	eax, byte [esi]
1399
	mov	eax, [eax*4+edx]
1400
	sub	edi, 3
1401
	mov	[edi], ax
1402
	shr	eax, 16
1403
	mov	[edi+2], al
1404
	loop	@b
1405
	pop	edx
1406
	movzx	esi, [ebx + gif.Header.lsd.ScreenHeight]
1407
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1408
	mov	edx, [edx + Image.Extended]
1409
	movzx	ecx, [edx + gif.Image.info.Top]
1410
	sub	esi, ecx
1411
	jbe	.convert_rgb_ret
1412
	imul	ecx, eax
1413
	lea	ecx, [ecx*3]
1414
	add	edi, ecx
1415
	cmp	si, [edx + gif.Image.info.Height]
1416
	jb	@f
1417
	mov	si, [edx + gif.Image.info.Height]
1418
@@:
1419
	movzx	ecx, [edx + gif.Image.info.Left]
1420
	sub	eax, ecx
1421
	jbe	.convert_rgb_ret
1422
	lea	ecx, [ecx*3]
1423
	add	edi, ecx
1424
	cmp	ax, [edx + gif.Image.info.Width]
1425
	jb	@f
1426
	mov	ax, [edx + gif.Image.info.Width]
1427
@@:
1428
	xchg	eax, ecx
1429
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1430
	sub	edx, ecx
1431
	mov	eax, [background_color]
1432
	lea	edx, [edx*3]
1433
.convert_rgb_loop:
1434
	push	ecx
1435
@@:
1436
	stosw
1437
	shr	eax, 16
1438
	stosb
1439
	loop	@b
1440
	pop	ecx
1441
	add	edi, edx
1442
	dec	esi
1443
	jnz	.convert_rgb_loop
1444
.convert_rgb_ret:
1445
	retn
1446
.rgb:
1447
	push	3
1448
	pop	eax
1449
	stdcall	img.decode.gif._.alloc_aux_img
1450
	test	eax, eax
1451
	jz	.previous
1452
	or	[prev_num_colors], -1
1453
	and	[prev_palette], 0
1454
	mov	ebx, [_data]
1455
	mov	esi, [prev_img_data]
1456
	mov	edi, [aux_img_data]
1457
	mov	[prev_img_data], edi
1458
	cmp	esi, edi
1459
	jz	@f
1460
	movzx	ecx, [ebx + gif.Header.lsd.ScreenHeight]
1461
	push	ecx
1462
	movzx	eax, [ebx + gif.Header.lsd.ScreenWidth]
1463
	imul	ecx, eax
1464
	lea	ecx, [ecx*3]
1465
	push	edi
1466
	rep	movsb
1467
	pop	edi
1468
	pop	esi
1469
	mov	edx, [edx + Image.Extended]
1470
	movzx	ecx, [edx + gif.Image.info.Top]
1471
	sub	esi, ecx
1472
	jbe	.rgb_ret
1473
	imul	ecx, eax
1474
	lea	ecx, [ecx*3]
1475
	add	edi, ecx
1476
	cmp	si, [edx + gif.Image.info.Height]
1477
	jb	@f
1478
	mov	si, [edx + gif.Image.info.Height]
1479
@@:
1480
	movzx	ecx, [edx + gif.Image.info.Left]
1481
	sub	eax, ecx
1482
	jbe	.rgb_ret
1483
	lea	ecx, [ecx*3]
1484
	add	edi, ecx
1485
	cmp	ax, [edx + gif.Image.info.Width]
1486
	jb	@f
1487
	mov	ax, [edx + gif.Image.info.Width]
1488
@@:
1489
	xchg	eax, ecx
1490
	movzx	edx, [ebx + gif.Header.lsd.ScreenWidth]
1491
	sub	edx, ecx
1492
	mov	eax, [background_color]
1493
	lea	edx, [edx*3]
1494
.rgb_loop:
1495
	push	ecx
1496
@@:
1497
	stosw
1498
	shr	eax, 16
1499
	stosb
1500
	loop	@b
1501
	pop	ecx
1502
	add	edi, edx
1503
	dec	esi
1504
	jnz	.rgb_loop
1505
.rgb_ret:
1506
	retn
1507
 
1508
endp
1509
 
1510
;;================================================================================================;;
1511
proc img.decode.gif._.alloc_aux_img ;/////////////////////////////////////////////////////////////;;
1512
;;------------------------------------------------------------------------------------------------;;
1513
;? Allocate auxiliary memory for previous image                                                   ;;
1514
;;------------------------------------------------------------------------------------------------;;
1515
;> eax = image type: 1 = bpp8, 3 = bpp24                                                          ;;
1516
;;------------------------------------------------------------------------------------------------;;
1517
;< eax = [aux_img_data]                                                                           ;;
1518
;;================================================================================================;;
1519
	cmp	[aux_img_type], eax
1520
	jae	@f
1521
	push	edx eax
1522
	movzx	ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
1523
	mul	ecx
1524
	movzx	ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
1525
	mul	ecx
1526
	invoke	mem.realloc, [aux_img_data], eax
1527
	pop	ecx edx
1528
	test	eax, eax
1529
	jz	@f
1530
	mov	[aux_img_type], ecx
1531
	mov	[aux_img_data], eax
1532
@@:	retn
1533
 
1534
endp
1535
 
1536
;;================================================================================================;;
1537
proc img.decode.gif._.alloc_aux_palette ;/////////////////////////////////////////////////////////;;
1538
;;------------------------------------------------------------------------------------------------;;
1539
;? Allocate and fill aux_palette                                                                  ;;
1540
;;------------------------------------------------------------------------------------------------;;
1541
;> esi -> palette, ecx = palette size                                                             ;;
1542
;;------------------------------------------------------------------------------------------------;;
1543
;< [aux_palette] set                                                                              ;;
1544
;;================================================================================================;;
1545
	mov	eax, [aux_palette]
1546
	test	eax, eax
1547
	jnz	@f
1548
	push	edx ecx
1549
	invoke	mem.alloc, 0x400
1550
	pop	ecx edx
1551
	test	eax, eax
1552
	jz	.ret
1553
	mov	[aux_palette], eax
1554
@@:
1555
	mov	edi, eax
1556
	rep	movsd
1557
.ret:
1558
	retn
1559
 
1560
endp
1561
 
1562
restore main_img
1563
restore transparent_color
1564
restore background_color
1565
restore prev_num_colors
1566
restore prev_palette
1567
restore max_color
1568
restore prev_img_data
1569
restore _data
1570
restore aux_img_data
1571
restore aux_img_type
1572
restore aux_palette
1573
 
1574
;;================================================================================================;;
717 mikedld 1575
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1576
;;================================================================================================;;
1577
;! Below is private data you should never use directly from your code                             ;;
1578
;;================================================================================================;;
1579
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1580
;;================================================================================================;;
1581
 
1582
 
1583
;