Subversion Repositories Kolibri OS

Rev

Rev 722 | Rev 999 | 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 ;;
10
;; General Public License as published by the Free Software Foundation, either version 3 of the   ;;
11
;; License, or (at your option) any later version.                                                ;;
12
;;                                                                                                ;;
13
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
14
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
15
;; General Public License for more details.                                                       ;;
16
;;                                                                                                ;;
17
;; You should have received a copy of the GNU General Public License along with Libs-Dev. If not, ;;
18
;; see .                                                            ;;
19
;;                                                                                                ;;
20
;;================================================================================================;;
21
;;                                                                                                ;;
22
;; References:                                                                                    ;;
23
;;   1. GIF LITE v3.0 (2004-2007)                                                                 ;;
24
;;      by Willow and Diamond                                                                     ;;
25
;;      svn://kolibrios.org/programs/media/gifview/trunk/gif_lite.inc                             ;;
26
;;   2. "GIF File Format Summary"                                                                 ;;
27
;;      from "Encyclopedia of Graphics File Formats" by O'Reilly                                  ;;
28
;;      http://www.fileformat.info/format/gif/                                                    ;;
29
;;   3. "LZW and GIF explained" (1987)                                                            ;;
30
;;      by Steve Blackstock, IEEE                                                                 ;;
31
;;      http://www.cis.udel.edu/~amer/CISC651/lzw.and.gif.explained.html                          ;;
32
;;   4. "Graphics Interchange Format (tm)" (June 15, 1987)                                        ;;
33
;;      by CompuServe Incorporated                                                                ;;
34
;;      http://examples.oreilly.de/english_examples/gff/CDROM/GFF/VENDSPEC/GIF/GIF87A.TXT         ;;
35
;;   5. "Graphics Interchange Format (sm)" (July 31, 1990)                                        ;;
36
;;      by CompuServe Incorporated                                                                ;;
37
;;      http://examples.oreilly.de/english_examples/gff/CDROM/GFF/VENDSPEC/GIF/GIF89A.TXT         ;;
38
;;                                                                                                ;;
39
;;================================================================================================;;
40
 
41
 
42
include 'gif.inc'
43
 
44
;;================================================================================================;;
45
proc img.is.gif _data, _length ;//////////////////////////////////////////////////////////////////;;
46
;;------------------------------------------------------------------------------------------------;;
47
;? Determine if raw data could be decoded (is in GIF format)                                      ;;
48
;;------------------------------------------------------------------------------------------------;;
49
;> _data = raw data as read from file/stream                                                      ;;
50
;> _length = data length                                                                          ;;
51
;;------------------------------------------------------------------------------------------------;;
52
;< eax = false / true                                                                             ;;
53
;;================================================================================================;;
54
	cmp	[_length], 6
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
85
  img		     dd ?
86
  global_color_table dd ?
87
endl
88
 
89
	push	ebx
90
 
91
	stdcall img.is.gif, [_data], [_length]
92
	or	eax, eax
93
	jz	.error
94
 
95
	mov	ebx, [_data]
96
;       cmp     [ebx + bmp.Header.info.Compression], bmp.BI_RGB
97
;       je      @f
98
;       mov     eax, [ebx + bmp.Header.file.Size]
99
;       cmp     eax, [_length]
100
;       jne     .error
101
 
102
	test	[ebx + gif.Header.lsd.Packed], gif.LSD.Packed.GlobalColorTableFlag
103
	jz	@f
104
	lea	eax, [ebx + sizeof.gif.Header]
105
	mov	[global_color_table], eax
106
	mov	cl, [ebx + gif.Header.lsd.Packed]
107
	and	cl, gif.LSD.Packed.SizeOfGlobalColorTableMask
108
	shr	cl, gif.LSD.Packed.SizeOfGlobalColorTableShift
109
	inc	cl
110
	mov	eax, 1
111
	shl	eax, cl
112
	lea	eax, [eax * 3]
113
	add	ebx, eax
114
    @@: add	ebx, sizeof.gif.Header
115
 
116
	mov	[img], 0
117
 
118
;   @@: cmp     byte[ebx + gif.Block.Introducer], gif.Block.Introducer.Extension
119
;       jne     .next_image
120
;       cmp     byte[ebx + gif.Extension.Label], gif.Extension.Label.Comment
121
;       jne     .error
122
;       add     ebx, sizeof.gif.Extension
123
;       stdcall ._.skip_data
124
;       mov     ebx, eax
125
;       jmp     @b
126
 
127
  .next_image:
128
	stdcall img._.new
129
	or	eax, eax
130
	jz	.error
131
	mov	edx, [img]
132
	mov	[eax + Image.Previous], edx
133
	mov	[img], eax
134
	mov	edx, eax
135
 
136
	mov	ecx, sizeof.gif.Image
137
	invoke	mem.alloc, ecx
138
	or	eax, eax
139
	jz	.error
140
	mov	[edx + Image.Extended], eax
141
 
142
	stdcall ._.process_extensions
143
 
144
	cmp	byte[ebx + gif.Block.Introducer], gif.Block.Introducer.ImageDescriptor
145
	jne	.error
146
	movzx	eax, [ebx + gif.ImageDescriptor.Width]
147
	movzx	ecx, [ebx + gif.ImageDescriptor.Height]
783 mikedld 148
	stdcall img._.resize_data, [img], eax, ecx
717 mikedld 149
	or	eax, eax
150
	jz	.error
151
 
722 mikedld 152
	xor	ecx, ecx
153
	mov	eax, [edx + Image.Extended]
717 mikedld 154
	test	[ebx + gif.ImageDescriptor.Packed], gif.ID.Packed.LocalColorTableFlag
155
	jz	@f
156
	mov	cl, [ebx + gif.ImageDescriptor.Packed]
157
	and	cl, gif.ID.Packed.SizeOfLocalColorTableMask
158
	shr	cl, gif.ID.Packed.SizeOfLocalColorTableShift
159
	inc	cl
160
	mov	eax, 1
161
	shl	eax, cl
162
	lea	ecx, [eax * sizeof.gif.RgbTriplet]
163
	lea	eax, [ecx + sizeof.gif.Image]
164
	invoke	mem.realloc, [edx + Image.Extended], eax
165
	or	eax, eax
166
	jz	.error
167
	mov	[edx + Image.Extended], eax
722 mikedld 168
    @@: mov	esi, ebx
169
	lea	edi, [eax + sizeof.gif.GraphicsControlExtension]
170
	add	ecx, sizeof.gif.ImageDescriptor
717 mikedld 171
	rep	movsb
172
 
722 mikedld 173
	mov	eax, [global_color_table]
717 mikedld 174
	test	[ebx + gif.ImageDescriptor.Packed], gif.ID.Packed.LocalColorTableFlag
175
	jz	@f
176
	lea	eax, [ebx + sizeof.gif.ImageDescriptor]
177
    @@: mov	ebx, esi
178
	stdcall ._.process_image, eax
179
 
180
  .decoded:
181
	or	eax, eax
182
	jz	@f
183
	stdcall img.destroy, [img]
184
	jmp	.error
185
 
186
    @@: mov	eax, [img]
187
	ret
188
 
189
  .error:
190
	xor	eax, eax
191
	pop	ebx
192
	ret
193
endp
194
 
195
;;================================================================================================;;
196
proc img.encode.gif _img, _p_length ;/////////////////////////////////////////////////////////////;;
197
;;------------------------------------------------------------------------------------------------;;
198
;? Encode image into raw data in GIF format                                                       ;;
199
;;------------------------------------------------------------------------------------------------;;
200
;> _img = pointer to image                                                                        ;;
201
;;------------------------------------------------------------------------------------------------;;
202
;< eax = 0 (error) or pointer to encoded data                                                     ;;
203
;< _p_length = encoded data length                                                                ;;
204
;;================================================================================================;;
205
	xor	eax, eax
206
	ret
207
endp
208
 
209
 
210
;;================================================================================================;;
211
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
212
;;================================================================================================;;
213
;! Below are private procs you should never call directly from your code                          ;;
214
;;================================================================================================;;
215
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
216
;;================================================================================================;;
217
 
218
 
219
;;================================================================================================;;
220
proc img.decode.gif._.skip_data ;/////////////////////////////////////////////////////////////////;;
221
;;------------------------------------------------------------------------------------------------;;
222
;? --- TBD ---                                                                                    ;;
223
;;------------------------------------------------------------------------------------------------;;
224
;> ebx = pointer to data blocks array                                                             ;;
225
;;------------------------------------------------------------------------------------------------;;
226
;< eax = pointer to data right after data blocks array                                            ;;
227
;;================================================================================================;;
228
	push	ecx
229
	xor	ecx, ecx
230
    @@: mov	cl, [esi]
231
	or	cl, cl
232
	jz	@f
233
	lea	esi, [esi + ecx + 1]
234
	jmp	@b
235
    @@: pop	ecx
236
	ret
237
endp
238
 
239
;;================================================================================================;;
240
proc img.decode.gif._.process_extensions ;////////////////////////////////////////////////////////;;
241
;;------------------------------------------------------------------------------------------------;;
242
;? --- TBD ---                                                                                    ;;
243
;;------------------------------------------------------------------------------------------------;;
244
;> ebx = raw image data                                                                           ;;
245
;> edx = image data                                                                               ;;
246
;;------------------------------------------------------------------------------------------------;;
247
;< --- TBD ---                                                                                    ;;
248
;;================================================================================================;;
249
	push	edx
250
	mov	esi, ebx
251
 
252
  .next_block:
253
	mov	al, [esi + gif.Block.Introducer]
254
	cmp	al, gif.Block.Introducer.Extension
255
	je	.ext_block
256
;       cmp     al, gif.Block.Introducer.ImageDescriptor
257
;       je      .exit
258
;       cmp     al, gif.Block.Introducer.EndOfFile
259
;       je      .exit
260
	jmp	.exit
261
 
262
  .ext_block:
263
	mov	al, [esi + gif.Extension.Label]
264
	cmp	al, gif.Extension.Label.PlainText
265
	je	.plain_text_ext
266
	cmp	al, gif.Extension.Label.GraphicsControl
267
	je	.graphics_control_ext
268
	cmp	al, gif.Extension.Label.Comment
269
	je	.comment_ext
270
	cmp	al, gif.Extension.Label.Application
271
	je	.application_ext
272
	jmp	.exit
273
 
274
  .plain_text_ext:
275
	add	esi, gif.PlainTextExtension.PlainTextData
276
	stdcall img.decode.gif._.skip_data
277
	jmp	.next_ext_block
278
 
279
  .graphics_control_ext:
280
	push	edi
281
	mov	edi, [edx + Image.Extended]
282
	add	edi, gif.Image.gce
283
	mov	ecx, sizeof.gif.GraphicsControlExtension
284
	rep	movsb
285
	pop	edi
286
	jmp	.next_ext_block
287
 
288
  .comment_ext:
289
	add	esi, gif.CommentExtension.CommentData
290
	stdcall img.decode.gif._.skip_data
291
	jmp	.next_ext_block
292
 
293
  .application_ext:
294
	add	esi, gif.ApplicationExtension.ApplicationData
295
	stdcall img.decode.gif._.skip_data
296
	jmp	.next_ext_block
297
 
298
  .next_ext_block:
722 mikedld 299
	mov	al, [esi + gif.Block.Introducer]
717 mikedld 300
	cmp	al, gif.Block.Introducer.EndOfData
301
	jne	.exit
722 mikedld 302
	inc	esi
717 mikedld 303
	jmp	.next_block
304
 
305
  .exit:
306
	mov	ebx, esi
307
	pop	edx
308
	ret
309
endp
310
 
311
;;================================================================================================;;
312
proc img.decode.gif._.process_image _color_table ;////////////////////////////////////////////////;;
313
;;------------------------------------------------------------------------------------------------;;
314
;? --- TBD ---                                                                                    ;;
315
;;------------------------------------------------------------------------------------------------;;
316
;> ebx = raw image data                                                                           ;;
317
;> edx = image data                                                                               ;;
318
;;------------------------------------------------------------------------------------------------;;
319
;< --- TBD ---                                                                                    ;;
320
;;================================================================================================;;
321
locals
322
  width      dd ?
323
  img_start  dd ?
324
  img_end    dd ?
325
  row_end    dd ?
326
  pass	     dd ?
327
  codesize   dd ?
328
  compsize   dd ?
329
  workarea   dd ?
330
  block_ofs  dd ?
331
  bit_count  dd ?
332
  CC	     dd ?
333
  EOI	     dd ?
334
endl
335
 
336
	invoke	mem.alloc, 16 * 1024
337
	mov	[workarea], eax
338
	or	eax, eax
339
	jz	.error
340
 
341
	mov	ecx, [edx + Image.Width]
342
	mov	[width], ecx
343
	mov	eax, [edx + Image.Height]
344
	imul	eax, ecx
345
;       lea     eax, [eax * 3]
346
	shl	eax, 2
347
	mov	[img_end], eax
348
	inc	eax
349
	mov	[row_end], eax
350
	and	[pass], 0
351
	mov	eax, [edx + Image.Extended]
352
	test	[eax + gif.Image.info.Packed], gif.ID.Packed.InterleaceFlag
353
	jz	@f
354
;       lea     ecx, [ecx * 3]
355
	shl	ecx, 2
356
	mov	[row_end], ecx
357
 
358
    @@: mov	esi, ebx
359
	mov	edi, [edx + Image.Data]
360
 
361
	push	edi
362
	movzx	ecx, byte[esi]
363
	inc	esi
364
	mov	[codesize], ecx
365
	inc	[codesize]
366
	mov	edi, [workarea]
367
	xor	eax, eax
368
	lodsb				; eax - block_count
369
	add	eax, esi
370
	mov	[block_ofs], eax
371
	mov	[bit_count], 8
372
	mov	eax, 1
373
	shl	eax, cl
374
	mov	[CC], eax
375
	mov	ecx, eax
376
	inc	eax
377
	mov	[EOI], eax
378
	mov	eax, gif.Null shl 16
379
  .filltable:
380
	stosd
381
	inc	eax
382
	loop	.filltable
383
	pop	edi
384
	mov	[img_start], edi
385
	add	[img_end], edi
386
	add	[row_end], edi
387
  .reinit:
388
	mov	edx, [EOI]
389
	inc	edx
390
	push	[codesize]
391
	pop	[compsize]
392
	call	.get_symbol
393
	cmp	eax, [CC]
394
	je	.reinit
395
	call	.output
396
  .cycle:
397
	movzx	ebx, ax
398
	call	.get_symbol
399
	cmp	eax, edx
400
	jae	.notintable
401
	cmp	eax, [CC]
402
	je	.reinit
403
	cmp	eax, [EOI]
404
	je	.end
405
	call	.output
406
  .add:
407
	mov	ecx, [workarea]
408
	mov	[ecx + edx * 4], ebx
409
	cmp	edx, 0x00000FFF
410
	jae	.cycle
411
	inc	edx
412
	bsr	ebx, edx
413
	cmp	ebx, [compsize]
414
	jne	.noinc
415
	inc	[compsize]
416
  .noinc:
417
	jmp	.cycle
418
  .notintable:
419
	push	eax
420
	mov	eax, ebx
421
	call	.output
422
	push	ebx
423
	movzx	eax, bx
424
	call	.output
425
	pop	ebx eax
426
	jmp	.add
427
  .end:
428
	mov	edi, [img_end]
429
	xor	eax, eax
430
 
431
  .exit:
432
	cmp	[workarea], 0
433
	je	@f
434
	invoke	mem.free, [workarea]
435
    @@: xor	eax, eax
436
	ret
437
 
438
  .error:
439
	cmp	[workarea], 0
440
	je	@f
441
	invoke	mem.free, [workarea]
442
    @@: xor	eax, eax
443
	inc	eax
444
	ret
445
 
446
;;------------------------------------------------------------------------------------------------;;
447
 
448
img.decode.gif._.process_image.get_symbol:
449
	mov	ecx, [compsize]
450
	push	ecx
451
	xor	eax, eax
452
 
453
  .shift:
454
	ror	byte[esi], 1
455
	rcr	eax,1
456
	dec	[bit_count]
457
	jnz	.loop1
458
	inc	esi
459
	cmp	esi, [block_ofs]
460
	jb	.noblock
461
	push	eax
462
	xor	eax, eax
463
	lodsb
464
	test	eax, eax
465
	jnz	.nextbl
466
	mov	eax, [EOI]
467
	sub	esi, 2
468
	add	esp, 8
469
	jmp	.exit
470
 
471
  .nextbl:
472
	add	eax, esi
473
	mov	[block_ofs], eax
474
	pop	eax
475
 
476
  .noblock:
477
	mov	[bit_count], 8
478
 
479
  .loop1:
480
	loop	.shift
481
	pop	ecx
482
	rol	eax, cl
483
 
484
  .exit:
485
	xor	ecx, ecx
486
	retn
487
 
488
;;------------------------------------------------------------------------------------------------;;
489
 
490
img.decode.gif._.process_image.output:
491
	push	esi eax edx
492
	mov	edx, [workarea]
493
 
494
  .next:
495
	pushw	[edx + eax * 4]
496
	mov	ax, [edx + eax * 4 + 2]
497
	inc	ecx
498
	cmp	ax, gif.Null
499
	jnz	.next
500
	shl	ebx, 16
501
	mov	bx, [esp]
502
 
503
  .loop2:
504
	pop	ax
505
 
506
	lea	esi, [eax * 3]
507
	add	esi, [_color_table]
508
 
509
	mov	esi, [esi]
510
	bswap	esi
511
	shr	esi, 8
512
	mov	[edi], esi
513
	add	edi, 4
514
 
515
	cmp	edi, [row_end]
516
	jb	.norowend
517
	mov	eax, [width]
518
;       lea     eax, [eax * 3]
519
	shl	eax, 2
520
	push	eax
521
	sub	edi, eax
522
	add	eax, eax
523
	cmp	[pass], 3
524
	je	@f
525
	add	eax, eax
526
	cmp	[pass], 2
527
	je	@f
528
	add	eax, eax
529
    @@: add	edi, eax
530
	pop	eax
531
	cmp	edi, [img_end]
532
	jb	.nextrow
533
	mov	edi, [img_start]
534
	inc	[pass]
535
	add	edi, eax
536
	cmp	[pass], 3
537
	je	@f
538
	add	edi, eax
539
	cmp	[pass], 2
540
	je	@f
541
	add	edi, eax
542
	add	edi, eax
543
    @@:
544
 
545
  .nextrow:
546
	add	eax, edi
547
	mov	[row_end], eax
548
	xor	eax, eax
549
 
550
  .norowend:
551
	loop	.loop2
552
	pop	edx eax esi
553
	retn
554
 
555
endp
556
 
557
 
558
;;================================================================================================;;
559
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
560
;;================================================================================================;;
561
;! Below is private data you should never use directly from your code                             ;;
562
;;================================================================================================;;
563
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
564
;;================================================================================================;;
565
 
566
 
567
;