Subversion Repositories Kolibri OS

Rev

Rev 783 | Rev 1079 | 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
;;================================================================================================;;
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 ?
999 diamond 87
  global_color_table_size dd ?
717 mikedld 88
endl
89
 
90
	push	ebx
91
 
999 diamond 92
; img.is.gif is called by caller (img.decode)
93
;	stdcall img.is.gif, [_data], [_length]
94
;	or	eax, eax
95
;	jz	.error
717 mikedld 96
 
999 diamond 97
	mov	[global_color_table_size], 0
717 mikedld 98
	mov	ebx, [_data]
99
 
100
	test	[ebx + gif.Header.lsd.Packed], gif.LSD.Packed.GlobalColorTableFlag
101
	jz	@f
102
	lea	eax, [ebx + sizeof.gif.Header]
103
	mov	[global_color_table], eax
104
	mov	cl, [ebx + gif.Header.lsd.Packed]
105
	and	cl, gif.LSD.Packed.SizeOfGlobalColorTableMask
106
	shr	cl, gif.LSD.Packed.SizeOfGlobalColorTableShift
999 diamond 107
	mov	eax, 2
717 mikedld 108
	shl	eax, cl
999 diamond 109
	mov	[global_color_table_size], eax
717 mikedld 110
	lea	eax, [eax * 3]
111
	add	ebx, eax
112
    @@: add	ebx, sizeof.gif.Header
113
 
114
	mov	[img], 0
115
 
116
;   @@: cmp     byte[ebx + gif.Block.Introducer], gif.Block.Introducer.Extension
117
;       jne     .next_image
118
;       cmp     byte[ebx + gif.Extension.Label], gif.Extension.Label.Comment
119
;       jne     .error
120
;       add     ebx, sizeof.gif.Extension
121
;       stdcall ._.skip_data
122
;       mov     ebx, eax
123
;       jmp     @b
124
 
125
  .next_image:
126
	stdcall img._.new
127
	or	eax, eax
128
	jz	.error
129
	mov	edx, [img]
130
	mov	[eax + Image.Previous], edx
999 diamond 131
	test	edx, edx
132
	jz	@f
133
	mov	[edx + Image.Next], eax
134
@@:
717 mikedld 135
	mov	[img], eax
136
	mov	edx, eax
999 diamond 137
	mov	[eax + Image.Type], Image.bpp8
717 mikedld 138
 
999 diamond 139
	invoke	mem.alloc, sizeof.gif.Image
717 mikedld 140
	or	eax, eax
141
	jz	.error
142
	mov	[edx + Image.Extended], eax
143
 
144
	stdcall ._.process_extensions
145
 
146
	cmp	byte[ebx + gif.Block.Introducer], gif.Block.Introducer.ImageDescriptor
147
	jne	.error
148
	movzx	eax, [ebx + gif.ImageDescriptor.Width]
149
	movzx	ecx, [ebx + gif.ImageDescriptor.Height]
783 mikedld 150
	stdcall img._.resize_data, [img], eax, ecx
717 mikedld 151
	or	eax, eax
152
	jz	.error
153
 
999 diamond 154
	mov	esi, ebx
155
	mov	edi, [edx + Image.Extended]
156
	mov	ecx, sizeof.gif.ImageDescriptor
157
	rep	movsb
158
 
159
	mov	edi, [edx + Image.Palette]
160
	mov	esi, [global_color_table]
161
	mov	ecx, [global_color_table_size]
717 mikedld 162
	test	[ebx + gif.ImageDescriptor.Packed], gif.ID.Packed.LocalColorTableFlag
163
	jz	@f
999 diamond 164
	lea	esi, [ebx + sizeof.gif.ImageDescriptor]
717 mikedld 165
	mov	cl, [ebx + gif.ImageDescriptor.Packed]
166
	and	cl, gif.ID.Packed.SizeOfLocalColorTableMask
167
	shr	cl, gif.ID.Packed.SizeOfLocalColorTableShift
999 diamond 168
	mov	eax, 2
717 mikedld 169
	shl	eax, cl
999 diamond 170
	mov	ecx, eax
171
	lea	eax, [eax*3]
172
	add	ebx, eax
173
@@:
174
	lodsd
175
	dec	esi
176
	bswap	eax
177
	shr	eax, 8
178
	stosd
179
	loop	@b
180
	add	ebx, sizeof.gif.ImageDescriptor
181
	stdcall ._.process_image
717 mikedld 182
 
183
  .decoded:
184
	or	eax, eax
185
	jz	@f
186
	stdcall img.destroy, [img]
187
	jmp	.error
188
 
189
    @@: mov	eax, [img]
190
	ret
191
 
192
  .error:
999 diamond 193
	mov	eax, [img]
194
	test	eax, eax
195
	jz	@f
196
	stdcall	img.destroy, eax
197
@@:
717 mikedld 198
	xor	eax, eax
199
	pop	ebx
200
	ret
201
endp
202
 
203
;;================================================================================================;;
204
proc img.encode.gif _img, _p_length ;/////////////////////////////////////////////////////////////;;
205
;;------------------------------------------------------------------------------------------------;;
206
;? Encode image into raw data in GIF format                                                       ;;
207
;;------------------------------------------------------------------------------------------------;;
208
;> _img = pointer to image                                                                        ;;
209
;;------------------------------------------------------------------------------------------------;;
210
;< eax = 0 (error) or pointer to encoded data                                                     ;;
211
;< _p_length = encoded data length                                                                ;;
212
;;================================================================================================;;
213
	xor	eax, eax
214
	ret
215
endp
216
 
217
 
218
;;================================================================================================;;
219
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
220
;;================================================================================================;;
221
;! Below are private procs you should never call directly from your code                          ;;
222
;;================================================================================================;;
223
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
224
;;================================================================================================;;
225
 
226
 
227
;;================================================================================================;;
228
proc img.decode.gif._.skip_data ;/////////////////////////////////////////////////////////////////;;
229
;;------------------------------------------------------------------------------------------------;;
230
;? --- TBD ---                                                                                    ;;
231
;;------------------------------------------------------------------------------------------------;;
232
;> ebx = pointer to data blocks array                                                             ;;
233
;;------------------------------------------------------------------------------------------------;;
234
;< eax = pointer to data right after data blocks array                                            ;;
235
;;================================================================================================;;
236
	push	ecx
237
	xor	ecx, ecx
238
    @@: mov	cl, [esi]
239
	or	cl, cl
240
	jz	@f
241
	lea	esi, [esi + ecx + 1]
242
	jmp	@b
243
    @@: pop	ecx
244
	ret
245
endp
246
 
247
;;================================================================================================;;
248
proc img.decode.gif._.process_extensions ;////////////////////////////////////////////////////////;;
249
;;------------------------------------------------------------------------------------------------;;
250
;? --- TBD ---                                                                                    ;;
251
;;------------------------------------------------------------------------------------------------;;
252
;> ebx = raw image data                                                                           ;;
253
;> edx = image data                                                                               ;;
254
;;------------------------------------------------------------------------------------------------;;
255
;< --- TBD ---                                                                                    ;;
256
;;================================================================================================;;
257
	push	edx
258
	mov	esi, ebx
259
 
260
  .next_block:
261
	mov	al, [esi + gif.Block.Introducer]
262
	cmp	al, gif.Block.Introducer.Extension
263
	je	.ext_block
264
;       cmp     al, gif.Block.Introducer.ImageDescriptor
265
;       je      .exit
266
;       cmp     al, gif.Block.Introducer.EndOfFile
267
;       je      .exit
268
	jmp	.exit
269
 
270
  .ext_block:
271
	mov	al, [esi + gif.Extension.Label]
272
	cmp	al, gif.Extension.Label.PlainText
273
	je	.plain_text_ext
274
	cmp	al, gif.Extension.Label.GraphicsControl
275
	je	.graphics_control_ext
276
	cmp	al, gif.Extension.Label.Comment
277
	je	.comment_ext
278
	cmp	al, gif.Extension.Label.Application
279
	je	.application_ext
280
	jmp	.exit
281
 
282
  .plain_text_ext:
283
	add	esi, gif.PlainTextExtension.PlainTextData
284
	stdcall img.decode.gif._.skip_data
285
	jmp	.next_ext_block
286
 
287
  .graphics_control_ext:
288
	push	edi
289
	mov	edi, [edx + Image.Extended]
290
	add	edi, gif.Image.gce
291
	mov	ecx, sizeof.gif.GraphicsControlExtension
292
	rep	movsb
293
	pop	edi
294
	jmp	.next_ext_block
295
 
296
  .comment_ext:
297
	add	esi, gif.CommentExtension.CommentData
298
	stdcall img.decode.gif._.skip_data
299
	jmp	.next_ext_block
300
 
301
  .application_ext:
302
	add	esi, gif.ApplicationExtension.ApplicationData
303
	stdcall img.decode.gif._.skip_data
304
	jmp	.next_ext_block
305
 
306
  .next_ext_block:
722 mikedld 307
	mov	al, [esi + gif.Block.Introducer]
717 mikedld 308
	cmp	al, gif.Block.Introducer.EndOfData
309
	jne	.exit
722 mikedld 310
	inc	esi
717 mikedld 311
	jmp	.next_block
312
 
313
  .exit:
314
	mov	ebx, esi
315
	pop	edx
316
	ret
317
endp
318
 
319
;;================================================================================================;;
999 diamond 320
proc img.decode.gif._.process_image ;/////////////////////////////////////////////////////////////;;
717 mikedld 321
;;------------------------------------------------------------------------------------------------;;
322
;? --- TBD ---                                                                                    ;;
323
;;------------------------------------------------------------------------------------------------;;
324
;> ebx = raw image data                                                                           ;;
325
;> edx = image data                                                                               ;;
326
;;------------------------------------------------------------------------------------------------;;
327
;< --- TBD ---                                                                                    ;;
328
;;================================================================================================;;
329
locals
330
  width      dd ?
331
  img_start  dd ?
332
  img_end    dd ?
333
  row_end    dd ?
334
  pass	     dd ?
335
  codesize   dd ?
336
  compsize   dd ?
337
  workarea   dd ?
338
  block_ofs  dd ?
339
  bit_count  dd ?
340
  CC	     dd ?
341
  EOI	     dd ?
342
endl
343
 
344
	invoke	mem.alloc, 16 * 1024
345
	mov	[workarea], eax
346
	or	eax, eax
347
	jz	.error
348
 
349
	mov	ecx, [edx + Image.Width]
350
	mov	[width], ecx
351
	mov	eax, [edx + Image.Height]
352
	imul	eax, ecx
353
	mov	[img_end], eax
354
	inc	eax
355
	mov	[row_end], eax
356
	and	[pass], 0
357
	mov	eax, [edx + Image.Extended]
358
	test	[eax + gif.Image.info.Packed], gif.ID.Packed.InterleaceFlag
359
	jz	@f
360
	mov	[row_end], ecx
361
 
362
    @@: mov	esi, ebx
363
	mov	edi, [edx + Image.Data]
364
 
365
	push	edi
366
	movzx	ecx, byte[esi]
367
	inc	esi
368
	mov	[codesize], ecx
369
	inc	[codesize]
370
	mov	edi, [workarea]
371
	xor	eax, eax
372
	lodsb				; eax - block_count
373
	add	eax, esi
374
	mov	[block_ofs], eax
375
	mov	[bit_count], 8
376
	mov	eax, 1
377
	shl	eax, cl
378
	mov	[CC], eax
379
	mov	ecx, eax
380
	inc	eax
381
	mov	[EOI], eax
382
	mov	eax, gif.Null shl 16
383
  .filltable:
384
	stosd
385
	inc	eax
386
	loop	.filltable
387
	pop	edi
388
	mov	[img_start], edi
389
	add	[img_end], edi
390
	add	[row_end], edi
391
  .reinit:
392
	mov	edx, [EOI]
393
	inc	edx
394
	push	[codesize]
395
	pop	[compsize]
396
	call	.get_symbol
397
	cmp	eax, [CC]
398
	je	.reinit
399
	call	.output
400
  .cycle:
401
	movzx	ebx, ax
402
	call	.get_symbol
403
	cmp	eax, edx
404
	jae	.notintable
405
	cmp	eax, [CC]
406
	je	.reinit
407
	cmp	eax, [EOI]
408
	je	.end
409
	call	.output
410
  .add:
411
	mov	ecx, [workarea]
412
	mov	[ecx + edx * 4], ebx
413
	cmp	edx, 0x00000FFF
414
	jae	.cycle
415
	inc	edx
416
	bsr	ebx, edx
417
	cmp	ebx, [compsize]
418
	jne	.noinc
419
	inc	[compsize]
420
  .noinc:
421
	jmp	.cycle
422
  .notintable:
423
	push	eax
424
	mov	eax, ebx
425
	call	.output
426
	push	ebx
427
	movzx	eax, bx
428
	call	.output
429
	pop	ebx eax
430
	jmp	.add
431
  .end:
432
	mov	edi, [img_end]
433
	xor	eax, eax
434
 
435
  .exit:
436
	cmp	[workarea], 0
437
	je	@f
438
	invoke	mem.free, [workarea]
439
    @@: xor	eax, eax
440
	ret
441
 
442
  .error:
443
	cmp	[workarea], 0
444
	je	@f
445
	invoke	mem.free, [workarea]
446
    @@: xor	eax, eax
447
	inc	eax
448
	ret
449
 
450
;;------------------------------------------------------------------------------------------------;;
451
 
452
img.decode.gif._.process_image.get_symbol:
453
	mov	ecx, [compsize]
454
	push	ecx
455
	xor	eax, eax
456
 
457
  .shift:
458
	ror	byte[esi], 1
459
	rcr	eax,1
460
	dec	[bit_count]
461
	jnz	.loop1
462
	inc	esi
463
	cmp	esi, [block_ofs]
464
	jb	.noblock
465
	push	eax
466
	xor	eax, eax
467
	lodsb
468
	test	eax, eax
469
	jnz	.nextbl
470
	mov	eax, [EOI]
471
	sub	esi, 2
472
	add	esp, 8
473
	jmp	.exit
474
 
475
  .nextbl:
476
	add	eax, esi
477
	mov	[block_ofs], eax
478
	pop	eax
479
 
480
  .noblock:
481
	mov	[bit_count], 8
482
 
483
  .loop1:
484
	loop	.shift
485
	pop	ecx
486
	rol	eax, cl
487
 
488
  .exit:
489
	xor	ecx, ecx
490
	retn
491
 
492
;;------------------------------------------------------------------------------------------------;;
493
 
494
img.decode.gif._.process_image.output:
495
	push	esi eax edx
496
	mov	edx, [workarea]
497
 
498
  .next:
499
	pushw	[edx + eax * 4]
500
	mov	ax, [edx + eax * 4 + 2]
501
	inc	ecx
502
	cmp	ax, gif.Null
503
	jnz	.next
504
	shl	ebx, 16
505
	mov	bx, [esp]
506
 
507
  .loop2:
508
	pop	ax
999 diamond 509
	stosb
717 mikedld 510
 
511
	cmp	edi, [row_end]
512
	jb	.norowend
513
	mov	eax, [width]
514
	push	eax
515
	sub	edi, eax
516
	add	eax, eax
517
	cmp	[pass], 3
518
	je	@f
519
	add	eax, eax
520
	cmp	[pass], 2
521
	je	@f
522
	add	eax, eax
523
    @@: add	edi, eax
524
	pop	eax
525
	cmp	edi, [img_end]
526
	jb	.nextrow
527
	mov	edi, [img_start]
528
	inc	[pass]
529
	add	edi, eax
530
	cmp	[pass], 3
531
	je	@f
532
	add	edi, eax
533
	cmp	[pass], 2
534
	je	@f
535
	add	edi, eax
536
	add	edi, eax
537
    @@:
538
 
539
  .nextrow:
540
	add	eax, edi
541
	mov	[row_end], eax
542
	xor	eax, eax
543
 
544
  .norowend:
545
	loop	.loop2
546
	pop	edx eax esi
547
	retn
548
 
549
endp
550
 
551
 
552
;;================================================================================================;;
553
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
554
;;================================================================================================;;
555
;! Below is private data you should never use directly from your code                             ;;
556
;;================================================================================================;;
557
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
558
;;================================================================================================;;
559
 
560
 
561
;