Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
717 mikedld 1
;;================================================================================================;;
999 diamond 2
;;//// libimg.asm //// (c) mike.dld, 2007-2008, (c) diamond, 2009 ////////////////////////////////;;
717 mikedld 3
;;================================================================================================;;
4
;;                                                                                                ;;
5
;; This file is part of Common development libraries (Libs-Dev).                                  ;;
6
;;                                                                                                ;;
7
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
999 diamond 8
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
9
;; of the License, or (at your option) any later version.                                         ;;
717 mikedld 10
;;                                                                                                ;;
11
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
12
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
999 diamond 13
;; Lesser General Public License for more details.                                                ;;
717 mikedld 14
;;                                                                                                ;;
999 diamond 15
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
16
;; If not, see .                                                    ;;
717 mikedld 17
;;                                                                                                ;;
18
;;================================================================================================;;
19
 
20
 
21
format MS COFF
22
 
23
public @EXPORT as 'EXPORTS'
24
 
25
include '../../../../struct.inc'
26
include '../../../../proc32.inc'
27
include '../../../../macros.inc'
999 diamond 28
purge section,mov,add,sub
717 mikedld 29
 
30
include 'libimg.inc'
31
 
32
section '.flat' code readable align 16
33
 
34
include 'bmp/bmp.asm'
35
include 'gif/gif.asm'
999 diamond 36
include 'jpeg/jpeg.asm'
1014 diamond 37
include 'png/png.asm'
1079 diamond 38
include 'tga/tga.asm'
39
include 'z80/z80.asm'
1102 diamond 40
include 'ico_cur/ico_cur.asm'
717 mikedld 41
 
42
;;================================================================================================;;
43
proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
44
;;------------------------------------------------------------------------------------------------;;
45
;? Library entry point (called after library load)                                                ;;
46
;;------------------------------------------------------------------------------------------------;;
47
;> eax = pointer to memory allocation routine                                                     ;;
48
;> ebx = pointer to memory freeing routine                                                        ;;
49
;> ecx = pointer to memory reallocation routine                                                   ;;
50
;> edx = pointer to library loading routine                                                       ;;
51
;;------------------------------------------------------------------------------------------------;;
52
;< eax = 1 (fail) / 0 (ok) (library initialization result)                                        ;;
53
;;================================================================================================;;
54
	mov	[mem.alloc], eax
55
	mov	[mem.free], ebx
56
	mov	[mem.realloc], ecx
57
	mov	[dll.load], edx
58
 
999 diamond 59
	call	img.initialize.jpeg
60
 
1079 diamond 61
	xor	eax, eax
62
	cpuid
63
	cmp	ecx, 'ntel'
64
	jnz	@f
65
	mov	dword [img._.do_rgb.handlers + (Image.bpp15-1)*4], img._.do_rgb.bpp15.intel
66
	mov	dword [img._.do_rgb.handlers + (Image.bpp16-1)*4], img._.do_rgb.bpp16.intel
67
  @@:
68
 
717 mikedld 69
  .ok:	xor	eax,eax
70
	ret
71
endp
72
 
73
;;================================================================================================;;
74
proc img.is_img _data, _length ;//////////////////////////////////////////////////////////////////;;
75
;;------------------------------------------------------------------------------------------------;;
76
;? --- TBD ---                                                                                    ;;
77
;;------------------------------------------------------------------------------------------------;;
78
;> --- TBD ---                                                                                    ;;
79
;;------------------------------------------------------------------------------------------------;;
80
;< --- TBD ---                                                                                    ;;
81
;;================================================================================================;;
82
	push	ebx
83
	mov	ebx, img._.formats_table
84
    @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
85
	or	eax, eax
86
	jnz	@f
87
	add	ebx, sizeof.FormatsTableEntry
88
	cmp	dword[ebx], 0
89
	jnz	@b
90
	xor	eax, eax
91
    @@: pop	ebx
92
	ret
93
endp
94
 
95
;;================================================================================================;;
96
proc img.info _data, _length ;////////////////////////////////////////////////////////////////////;;
97
;;------------------------------------------------------------------------------------------------;;
98
;? --- TBD ---                                                                                    ;;
99
;;------------------------------------------------------------------------------------------------;;
100
;> --- TBD ---                                                                                    ;;
101
;;------------------------------------------------------------------------------------------------;;
102
;< --- TBD ---                                                                                    ;;
103
;;================================================================================================;;
104
	xor	eax, eax
105
	ret
106
endp
107
 
108
;;================================================================================================;;
109
proc img.from_file _filename ;////////////////////////////////////////////////////////////////////;;
110
;;------------------------------------------------------------------------------------------------;;
111
;? --- TBD ---                                                                                    ;;
112
;;------------------------------------------------------------------------------------------------;;
113
;> --- TBD ---                                                                                    ;;
114
;;------------------------------------------------------------------------------------------------;;
115
;< eax = 0 / pointer to image                                                                     ;;
116
;;================================================================================================;;
117
	xor	eax, eax
118
	ret
119
endp
120
 
121
;;================================================================================================;;
122
proc img.to_file _img, _filename ;////////////////////////////////////////////////////////////////;;
123
;;------------------------------------------------------------------------------------------------;;
124
;? --- TBD ---                                                                                    ;;
125
;;------------------------------------------------------------------------------------------------;;
126
;> --- TBD ---                                                                                    ;;
127
;;------------------------------------------------------------------------------------------------;;
128
;< eax = false / true                                                                             ;;
129
;;================================================================================================;;
130
	xor	eax, eax
131
	ret
132
endp
133
 
134
;;================================================================================================;;
135
proc img.from_rgb _rgb_data ;/////////////////////////////////////////////////////////////////////;;
136
;;------------------------------------------------------------------------------------------------;;
137
;? --- TBD ---                                                                                    ;;
138
;;------------------------------------------------------------------------------------------------;;
139
;> --- TBD ---                                                                                    ;;
140
;;------------------------------------------------------------------------------------------------;;
141
;< eax = 0 / pointer to image                                                                     ;;
142
;;================================================================================================;;
143
	xor	eax, eax
144
	ret
145
endp
146
 
147
;;================================================================================================;;
1001 diamond 148
proc img.to_rgb2 _img, _out ;/////////////////////////////////////////////////////////////////////;;
149
;;------------------------------------------------------------------------------------------------;;
150
;? --- TBD ---                                                                                    ;;
151
;;------------------------------------------------------------------------------------------------;;
152
;> --- TBD ---                                                                                    ;;
153
;;------------------------------------------------------------------------------------------------;;
154
;< --- TBD ---                                                                                    ;;
155
;;================================================================================================;;
156
	push	esi edi
157
	mov	esi, [_img]
158
	stdcall	img._.validate, esi
159
	or	eax, eax
160
	jnz	.ret
161
	mov	edi, [_out]
162
	call	img._.do_rgb
163
.ret:
164
	pop	edi esi
165
	ret
166
endp
167
 
168
;;================================================================================================;;
717 mikedld 169
proc img.to_rgb _img ;////////////////////////////////////////////////////////////////////////////;;
170
;;------------------------------------------------------------------------------------------------;;
171
;? --- TBD ---                                                                                    ;;
172
;;------------------------------------------------------------------------------------------------;;
173
;> --- TBD ---                                                                                    ;;
174
;;------------------------------------------------------------------------------------------------;;
175
;< eax = 0 / pointer to rgb_data (array of [rgb] triplets)                                        ;;
176
;;================================================================================================;;
177
	push	esi edi
1001 diamond 178
	mov	esi, [_img]
179
	stdcall img._.validate, esi
717 mikedld 180
	or	eax, eax
181
	jnz	.error
182
 
183
	mov	esi, [_img]
184
	mov	ecx, [esi + Image.Width]
185
	imul	ecx, [esi + Image.Height]
186
	lea	eax, [ecx * 3 + 4 * 3]
187
	invoke	mem.alloc, eax
188
	or	eax, eax
189
	jz	.error
190
 
191
	mov	edi, eax
192
	push	eax
193
	mov	eax, [esi + Image.Width]
194
	stosd
195
	mov	eax, [esi + Image.Height]
196
	stosd
1001 diamond 197
	call	img._.do_rgb
198
	pop	eax
199
	pop	edi esi
200
	ret
201
 
202
  .error:
203
	xor	eax, eax
204
	pop	edi esi
205
	ret
206
endp
207
 
208
;;================================================================================================;;
209
proc img._.do_rgb ;///////////////////////////////////////////////////////////////////////////////;;
210
;;------------------------------------------------------------------------------------------------;;
211
;? --- TBD ---                                                                                    ;;
212
;;------------------------------------------------------------------------------------------------;;
213
;> --- TBD ---                                                                                    ;;
214
;;------------------------------------------------------------------------------------------------;;
215
;< --- TBD ---                                                                                    ;;
216
;;================================================================================================;;
217
	mov	ecx, [esi + Image.Width]
218
	imul	ecx, [esi + Image.Height]
999 diamond 219
	mov	eax, [esi + Image.Type]
1079 diamond 220
	jmp	dword [.handlers + (eax-1)*4]
221
 
222
align 16
223
.bpp8:
224
; 8 BPP -> 24 BPP
225
	push	ebx
226
	mov	ebx, [esi + Image.Palette]
717 mikedld 227
	mov	esi, [esi + Image.Data]
1079 diamond 228
@@:
229
	movzx	eax, byte [esi]
230
	add	esi, 1
231
	mov	eax, [ebx + eax*4]
232
	mov	[edi], eax
233
	add	edi, 3
234
	sub	ecx, 1
235
	jnz	@b
236
	pop	ebx
237
	ret
717 mikedld 238
 
1079 diamond 239
; 15 BPP -> 24 BPP
240
.bpp15.intel:
241
	push	ebx ebp
242
	sub	ecx, 4
243
	jb	.bpp15.tail
244
align 16
245
.bpp15.intel.loop:
246
repeat 2
247
	mov	ebx, [esi]
248
	mov	al, [esi]
249
	mov	ah, [esi+1]
250
	add	esi, 4
251
	and	al, 0x1F
252
	and	ah, 0x1F shl 2
253
	mov	ebp, ebx
254
	mov	dl, al
255
	mov	dh, ah
256
	shr	al, 2
257
	shr	ah, 4
258
	shl	dl, 3
259
	shl	dh, 1
260
	and	ebp, 0x1F shl 5
261
	add	al, dl
262
	add	ah, dh
263
	shr	ebp, 2
264
	mov	[edi], al
265
	mov	[edi+2], ah
266
	mov	eax, ebx
267
	mov	ebx, ebp
1015 diamond 268
	shr	eax, 16
1079 diamond 269
	shr	ebx, 5
270
	add	ebx, ebp
271
	mov	ebp, eax
272
	mov	[edi+1], bl
273
	and	eax, (0x1F) or (0x1F shl 10)
274
	and	ebp, 0x1F shl 5
275
	lea	edx, [eax+eax]
276
	shr	al, 2
277
	mov	ebx, ebp
278
	shr	ah, 4
279
	shl	dl, 2
280
	shr	ebx, 2
281
	shr	ebp, 7
282
	add	al, dl
283
	add	ah, dh
284
	mov	[edi+3], al
285
	add	ebx, ebp
286
	mov	[edi+5], ah
287
	mov	[edi+4], bl
288
	add	edi, 6
289
end repeat
290
	sub	ecx, 4
291
	jnb	.bpp15.intel.loop
292
.bpp15.tail:
293
	add	ecx, 4
294
	jz	.bpp15.done
295
@@:
296
	movzx	eax, word [esi]
297
	mov	ebx, eax
298
	add	esi, 2
299
	and	eax, (0x1F) or (0x1F shl 10)
300
	and	ebx, 0x1F shl 5
301
	lea	edx, [eax+eax]
302
	shr	al, 2
303
	mov	ebp, ebx
304
	shr	ebx, 2
305
	shr	ah, 4
306
	shl	dl, 2
307
	shr	ebp, 7
308
	add	eax, edx
309
	add	ebx, ebp
310
	mov	[edi], al
311
	mov	[edi+1], bl
312
	mov	[edi+2], ah
313
	add	edi, 3
314
	sub	ecx, 1
315
	jnz	@b
316
.bpp15.done:
317
	pop	ebp ebx
318
	ret
319
 
320
.bpp15.amd:
321
	push	ebx ebp
322
	sub	ecx, 4
323
	jb	.bpp15.tail
324
align 16
325
.bpp15.amd.loop:
326
repeat 4
327
if (% mod 2) = 1
328
	mov	eax, dword [esi]
329
	mov	ebx, dword [esi]
330
else
331
	movzx	eax, word [esi]
332
	mov	ebx, eax
333
end if
334
	add	esi, 2
335
	and	eax, (0x1F) or (0x1F shl 10)
336
	and	ebx, 0x1F shl 5
337
	lea	edx, [eax+eax]
338
	shr	al, 2
339
	mov	ebp, ebx
340
	shr	ebx, 2
341
	shr	ah, 4
342
	shl	dl, 2
343
	shr	ebp, 7
344
	add	eax, edx
345
	add	ebx, ebp
346
	mov	[edi], al
347
	mov	[edi+1], bl
348
	mov	[edi+2], ah
349
	add	edi, 3
350
end repeat
351
	sub	ecx, 4
352
	jnb	.bpp15.amd.loop
353
	jmp	.bpp15.tail
354
 
355
; 16 BPP -> 24 BPP
356
.bpp16.intel:
357
	push	ebx ebp
358
	sub	ecx, 4
359
	jb	.bpp16.tail
360
align 16
361
.bpp16.intel.loop:
362
repeat 2
363
	mov	ebx, [esi]
364
	mov	al, [esi]
365
	mov	ah, [esi+1]
1015 diamond 366
	add	esi, 4
1079 diamond 367
	and	al, 0x1F
368
	and	ah, 0x1F shl 3
369
	mov	ebp, ebx
370
	mov	dl, al
371
	mov	dh, ah
372
	shr	al, 2
373
	shr	ah, 5
374
	shl	dl, 3
375
	and	ebp, 0x3F shl 5
376
	add	al, dl
377
	add	ah, dh
378
	shr	ebp, 3
379
	mov	[edi], al
380
	mov	[edi+2], ah
381
	mov	eax, ebx
382
	mov	ebx, ebp
383
	shr	eax, 16
384
	shr	ebx, 6
385
	add	ebx, ebp
386
	mov	ebp, eax
387
	mov	[edi+1], bl
388
	and	eax, (0x1F) or (0x1F shl 11)
389
	and	ebp, 0x3F shl 5
390
	mov	edx, eax
391
	shr	al, 2
392
	mov	ebx, ebp
393
	shr	ah, 5
394
	shl	dl, 3
395
	shr	ebx, 3
396
	shr	ebp, 9
397
	add	al, dl
398
	add	ah, dh
399
	mov	[edi+3], al
400
	add	ebx, ebp
401
	mov	[edi+5], ah
402
	mov	[edi+4], bl
403
	add	edi, 6
404
end repeat
405
	sub	ecx, 4
406
	jnb	.bpp16.intel.loop
407
.bpp16.tail:
408
	add	ecx, 4
409
	jz	.bpp16.done
410
@@:
411
	movzx	eax, word [esi]
412
	mov	ebx, eax
413
	add	esi, 2
414
	and	eax, (0x1F) or (0x1F shl 11)
415
	and	ebx, 0x3F shl 5
416
	mov	edx, eax
417
	shr	al, 2
418
	mov	ebp, ebx
419
	shr	ebx, 3
420
	shr	ah, 5
421
	shl	dl, 3
422
	shr	ebp, 9
423
	add	eax, edx
424
	add	ebx, ebp
425
	mov	[edi], al
426
	mov	[edi+1], bl
427
	mov	[edi+2], ah
1015 diamond 428
	add	edi, 3
429
	sub	ecx, 1
430
	jnz	@b
1079 diamond 431
.bpp16.done:
432
	pop	ebp ebx
717 mikedld 433
	ret
434
 
1079 diamond 435
.bpp16.amd:
436
	push	ebx ebp
437
	sub	ecx, 4
438
	jb	.bpp16.tail
439
align 16
440
.bpp16.amd.loop:
441
repeat 4
442
if (% mod 2) = 1
443
	mov	eax, dword [esi]
444
	mov	ebx, dword [esi]
445
else
446
	movzx	eax, word [esi]
447
	mov	ebx, eax
448
end if
449
	add	esi, 2
450
	and	eax, (0x1F) or (0x1F shl 11)
451
	and	ebx, 0x3F shl 5
452
	mov	edx, eax
453
	shr	al, 2
454
	mov	ebp, ebx
455
	shr	ebx, 3
456
	shr	ah, 5
457
	shl	dl, 3
458
	shr	ebp, 9
459
	add	eax, edx
460
	add	ebx, ebp
461
	mov	[edi], al
462
	mov	[edi+1], bl
463
	mov	[edi+2], ah
464
	add	edi, 3
465
end repeat
466
	sub	ecx, 4
467
	jnb	.bpp16.amd.loop
468
	jmp	.bpp16.tail
469
 
470
align 16
999 diamond 471
.bpp24:
472
; 24 BPP -> 24 BPP
473
	lea	ecx, [ecx*3 + 3]
474
	mov	esi, [esi + Image.Data]
475
	shr	ecx, 2
476
	rep	movsd
477
	ret
478
 
1079 diamond 479
align 16
480
.bpp32:
481
; 32 BPP -> 24 BPP
999 diamond 482
	mov	esi, [esi + Image.Data]
1079 diamond 483
 
484
    @@:
485
	mov	eax, [esi]
1015 diamond 486
	mov	[edi], ax
487
	shr	eax, 16
488
	mov	[edi+2], al
1079 diamond 489
	add	esi, 4
999 diamond 490
	add	edi, 3
491
	sub	ecx, 1
492
	jnz	@b
1079 diamond 493
 
494
    @@:
999 diamond 495
	ret
1079 diamond 496
 
717 mikedld 497
endp
498
 
499
;;================================================================================================;;
1102 diamond 500
proc img.decode _data, _length, _options ;////////////////////////////////////////////////////////;;
717 mikedld 501
;;------------------------------------------------------------------------------------------------;;
502
;? --- TBD ---                                                                                    ;;
503
;;------------------------------------------------------------------------------------------------;;
504
;> --- TBD ---                                                                                    ;;
505
;;------------------------------------------------------------------------------------------------;;
506
;< eax = 0 / pointer to image                                                                     ;;
507
;;================================================================================================;;
508
	push	ebx
509
	mov	ebx, img._.formats_table
510
    @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
511
	or	eax, eax
512
	jnz	@f
513
	add	ebx, sizeof.FormatsTableEntry
1102 diamond 514
	cmp	dword[ebx], eax ;0
999 diamond 515
	jnz	@b
1102 diamond 516
	pop	ebx
717 mikedld 517
	ret
1102 diamond 518
    @@: mov	eax, [ebx + FormatsTableEntry.Decode]
519
	pop	ebx
520
	leave
521
	jmp	eax
717 mikedld 522
endp
523
 
524
;;================================================================================================;;
1102 diamond 525
proc img.encode _img, _p_length, _options ;///////////////////////////////////////////////////////;;
717 mikedld 526
;;------------------------------------------------------------------------------------------------;;
527
;? --- TBD ---                                                                                    ;;
528
;;------------------------------------------------------------------------------------------------;;
529
;> --- TBD ---                                                                                    ;;
530
;;------------------------------------------------------------------------------------------------;;
531
;< eax = 0 / pointer to encoded data                                                              ;;
532
;< [_p_length] = data length                                                                      ;;
533
;;================================================================================================;;
534
	xor	eax, eax
535
	ret
536
endp
537
 
538
;;================================================================================================;;
999 diamond 539
proc img.create _width, _height, _type ;//////////////////////////////////////////////////////////;;
717 mikedld 540
;;------------------------------------------------------------------------------------------------;;
541
;? --- TBD ---                                                                                    ;;
542
;;------------------------------------------------------------------------------------------------;;
543
;> --- TBD ---                                                                                    ;;
544
;;------------------------------------------------------------------------------------------------;;
545
;< eax = 0 / pointer to image                                                                     ;;
546
;;================================================================================================;;
547
	push	ecx
548
 
549
	stdcall img._.new
550
	or	eax, eax
551
	jz	.error
552
 
999 diamond 553
	mov	ecx, [_type]
554
	mov	[eax + Image.Type], ecx
555
 
717 mikedld 556
	push	eax
557
 
783 mikedld 558
	stdcall img._.resize_data, eax, [_width], [_height]
717 mikedld 559
	or	eax, eax
560
	jz	.error.2
561
 
562
	pop	eax
999 diamond 563
	jmp	.ret
717 mikedld 564
 
565
  .error.2:
566
;       pop     eax
567
	stdcall img._.delete; eax
568
	xor	eax, eax
569
 
570
  .error:
999 diamond 571
  .ret:
717 mikedld 572
	pop	ecx
573
	ret
574
endp
575
 
576
;;================================================================================================;;
1079 diamond 577
proc img.destroy.layer _img ;/////////////////////////////////////////////////////////////////////;;
578
;;------------------------------------------------------------------------------------------------;;
579
;? --- TBD ---                                                                                    ;;
580
;;------------------------------------------------------------------------------------------------;;
581
;> --- TBD ---                                                                                    ;;
582
;;------------------------------------------------------------------------------------------------;;
583
;< eax = false / true                                                                             ;;
584
;;================================================================================================;;
585
	mov	eax, [_img]
586
	mov	edx, [eax + Image.Previous]
587
	test	edx, edx
588
	jz	@f
589
	push	[eax + Image.Next]
590
	pop	[edx + Image.Next]
591
@@:
592
	mov	edx, [eax + Image.Next]
593
	test	edx, edx
594
	jz	@f
595
	push	[eax + Image.Previous]
596
	pop	[edx + Image.Previous]
597
@@:
598
	stdcall img._.delete, eax
599
	ret
600
endp
601
 
602
;;================================================================================================;;
717 mikedld 603
proc img.destroy _img ;///////////////////////////////////////////////////////////////////////////;;
604
;;------------------------------------------------------------------------------------------------;;
605
;? --- TBD ---                                                                                    ;;
606
;;------------------------------------------------------------------------------------------------;;
607
;> --- TBD ---                                                                                    ;;
608
;;------------------------------------------------------------------------------------------------;;
609
;< eax = false / true                                                                             ;;
610
;;================================================================================================;;
1079 diamond 611
	push	1
612
	mov	eax, [_img]
613
	mov	eax, [eax + Image.Previous]
614
.destroy_prev_loop:
615
	test	eax, eax
616
	jz	.destroy_prev_done
617
	pushd	[eax + Image.Previous]
618
	stdcall	img._.delete, eax
619
	test	eax, eax
620
	jnz	@f
621
	mov	byte [esp+4], 0
622
@@:
623
	pop	eax
624
	jmp	.destroy_prev_loop
625
.destroy_prev_done:
626
	mov	eax, [_img]
627
.destroy_next_loop:
628
	pushd	[eax + Image.Next]
629
	stdcall	img._.delete, eax
630
	test	eax, eax
631
	jnz	@f
632
	mov	byte [esp+4], 0
633
@@:
634
	pop	eax
635
	test	eax, eax
636
	jnz	.destroy_next_loop
637
	pop	eax
717 mikedld 638
	ret
639
endp
640
 
641
;;================================================================================================;;
783 mikedld 642
proc img.count _img ;/////////////////////////////////////////////////////////////////////////////;;
717 mikedld 643
;;------------------------------------------------------------------------------------------------;;
783 mikedld 644
;? Get number of images in the list (e.g. in animated GIF file)                                   ;;
717 mikedld 645
;;------------------------------------------------------------------------------------------------;;
783 mikedld 646
;> _img = pointer to image                                                                        ;;
717 mikedld 647
;;------------------------------------------------------------------------------------------------;;
783 mikedld 648
;< eax = -1 (fail) / >0 (ok)                                                                      ;;
717 mikedld 649
;;================================================================================================;;
783 mikedld 650
	push	ecx edx
651
	mov	edx, [_img]
652
	stdcall img._.validate, edx
717 mikedld 653
	or	eax, eax
783 mikedld 654
	jnz	.error
717 mikedld 655
 
783 mikedld 656
    @@: mov	eax, [edx + Image.Previous]
657
	or	eax, eax
658
	jz	@f
659
	mov	edx, eax
660
	jmp	@b
717 mikedld 661
 
783 mikedld 662
    @@: xor	ecx, ecx
663
    @@: inc	ecx
664
	mov	eax, [edx + Image.Next]
665
	or	eax, eax
666
	jz	.exit
667
	mov	edx, eax
668
	jmp	@b
669
 
670
  .exit:
671
	mov	eax, ecx
672
	pop	edx ecx
673
	ret
674
 
717 mikedld 675
  .error:
783 mikedld 676
	or	eax, -1
677
	pop	edx ecx
717 mikedld 678
	ret
679
endp
680
 
783 mikedld 681
;;//// image processing //////////////////////////////////////////////////////////////////////////;;
682
 
717 mikedld 683
;;================================================================================================;;
684
proc img.lock_bits _img, _start_line, _end_line ;/////////////////////////////////////////////////;;
685
;;------------------------------------------------------------------------------------------------;;
686
;? --- TBD ---                                                                                    ;;
687
;;------------------------------------------------------------------------------------------------;;
688
;> --- TBD ---                                                                                    ;;
689
;;------------------------------------------------------------------------------------------------;;
690
;< eax = 0 / pointer to bits                                                                      ;;
691
;;================================================================================================;;
692
	xor	eax, eax
693
	ret
694
endp
695
 
696
;;================================================================================================;;
697
proc img.unlock_bits _img, _lock ;////////////////////////////////////////////////////////////////;;
698
;;------------------------------------------------------------------------------------------------;;
699
;? --- TBD ---                                                                                    ;;
700
;;------------------------------------------------------------------------------------------------;;
701
;> --- TBD ---                                                                                    ;;
702
;;------------------------------------------------------------------------------------------------;;
703
;< eax = false / true                                                                             ;;
704
;;================================================================================================;;
705
	xor	eax, eax
706
	ret
707
endp
708
 
709
;;================================================================================================;;
1079 diamond 710
proc img.flip.layer _img, _flip_kind ;////////////////////////////////////////////////////////////;;
717 mikedld 711
;;------------------------------------------------------------------------------------------------;;
1079 diamond 712
;? Flip image layer                                                                               ;;
717 mikedld 713
;;------------------------------------------------------------------------------------------------;;
783 mikedld 714
;> _img = pointer to image                                                                        ;;
715
;> _flip_kind = one of FLIP_* constants                                                           ;;
717 mikedld 716
;;------------------------------------------------------------------------------------------------;;
783 mikedld 717
;< eax = false / true                                                                             ;;
717 mikedld 718
;;================================================================================================;;
719
locals
720
  scanline_len dd ?
721
endl
722
 
999 diamond 723
	push	ebx esi edi
724
	mov	ebx, [_img]
725
	stdcall img._.validate, ebx
717 mikedld 726
	or	eax, eax
727
	jnz	.error
728
 
999 diamond 729
	mov	ecx, [ebx + Image.Height]
730
	mov	eax, [ebx + Image.Width]
731
	call	img._.get_scanline_len
717 mikedld 732
	mov	[scanline_len], eax
733
 
734
	test	[_flip_kind], FLIP_VERTICAL
735
	jz	.dont_flip_vert
736
 
737
	imul	eax, ecx
738
	sub	eax, [scanline_len]
739
	shr	ecx, 1
999 diamond 740
	mov	esi, [ebx + Image.Data]
717 mikedld 741
	lea	edi, [esi + eax]
742
 
743
  .next_line_vert:
744
	push	ecx
745
 
746
	mov	ecx, [scanline_len]
999 diamond 747
	push	ecx
783 mikedld 748
	shr	ecx, 2
999 diamond 749
    @@: mov	eax, [esi]
717 mikedld 750
	xchg	eax, [edi]
999 diamond 751
	mov	[esi], eax
752
	add	esi, 4
717 mikedld 753
	add	edi, 4
999 diamond 754
	sub	ecx, 1
755
	jnz	@b
756
	pop	ecx
757
	and	ecx, 3
758
	jz	.cont_line_vert
759
    @@:
760
	mov	al, [esi]
761
	xchg	al, [edi]
762
	mov	[esi], al
763
	add	esi, 1
764
	add	edi, 1
783 mikedld 765
	dec	ecx
717 mikedld 766
	jnz	@b
999 diamond 767
    .cont_line_vert:
717 mikedld 768
 
783 mikedld 769
	pop	ecx
717 mikedld 770
	mov	eax, [scanline_len]
771
	shl	eax, 1
772
	sub	edi, eax
773
	dec	ecx
774
	jnz	.next_line_vert
775
 
776
  .dont_flip_vert:
777
 
778
	test	[_flip_kind], FLIP_HORIZONTAL
779
	jz	.exit
780
 
999 diamond 781
	mov	ecx, [ebx + Image.Height]
782
	mov	eax, [ebx + Image.Type]
783
	mov	esi, [ebx + Image.Data]
784
	mov	edi, [scanline_len]
785
	add	edi, esi
1079 diamond 786
	jmp	dword [.handlers_horz + (eax-1)*4]
717 mikedld 787
 
1079 diamond 788
.bpp32_horz:
999 diamond 789
	sub	edi, 4
790
 
783 mikedld 791
  .next_line_horz:
792
	push	ecx esi edi
793
 
794
	mov	ecx, [scanline_len]
795
	shr	ecx, 3
796
    @@: mov	eax, [esi]
797
	xchg	eax, [edi]
798
	mov	[esi], eax
799
	add	esi, 4
800
	add	edi, -4
999 diamond 801
	sub	ecx, 1
783 mikedld 802
	jnz	@b
803
 
804
	pop	edi esi ecx
805
	add	esi, [scanline_len]
806
	add	edi, [scanline_len]
807
	dec	ecx
808
	jnz	.next_line_horz
999 diamond 809
	jmp	.exit
783 mikedld 810
 
1079 diamond 811
.bpp1x_horz:
812
	sub	edi, 2
813
  .next_line_horz1x:
814
	push	ecx esi edi
815
 
816
	mov	ecx, [ebx + Image.Width]
817
    @@: mov	ax, [esi]
818
	mov	dx, [edi]
819
	mov	[edi], ax
820
	mov	[esi], dx
821
	add	esi, 2
822
	sub	edi, 2
823
	sub	ecx, 2
824
	ja	@b
825
 
826
	pop	edi esi ecx
827
	add	esi, [scanline_len]
828
	add	edi, [scanline_len]
829
	dec	ecx
830
	jnz	.next_line_horz1x
831
	jmp	.exit
832
 
833
.bpp8_horz:
999 diamond 834
	dec	edi
835
  .next_line_horz8:
836
	push	ecx esi edi
837
 
838
	mov	ecx, [scanline_len]
839
	shr	ecx, 1
840
    @@: mov	al, [esi]
841
	mov	dl, [edi]
842
	mov	[edi], al
843
	mov	[esi], dl
844
	add	esi, 1
845
	sub	edi, 1
846
	sub	ecx, 1
847
	jnz	@b
848
 
849
	pop	edi esi ecx
850
	add	esi, [scanline_len]
851
	add	edi, [scanline_len]
852
	dec	ecx
853
	jnz	.next_line_horz8
854
	jmp	.exit
855
 
1079 diamond 856
.bpp24_horz:
999 diamond 857
	sub	edi, 3
1079 diamond 858
  .next_line_horz24:
999 diamond 859
	push	ecx esi edi
860
 
861
	mov	ecx, [ebx + Image.Width]
862
    @@:
863
	mov	al, [esi]
864
	mov	dl, [edi]
865
	mov	[edi], al
866
	mov	[esi], dl
867
	mov	al, [esi+1]
868
	mov	dl, [edi+1]
869
	mov	[edi+1], al
870
	mov	[esi+1], dl
871
	mov	al, [esi+2]
872
	mov	dl, [edi+2]
873
	mov	[edi+2], al
874
	mov	[esi+2], dl
875
	add	esi, 3
876
	sub	edi, 3
1079 diamond 877
	sub	ecx, 2
878
	ja	@b
999 diamond 879
 
880
	pop	edi esi ecx
881
	add	esi, [scanline_len]
882
	add	edi, [scanline_len]
883
	dec	ecx
1079 diamond 884
	jnz	.next_line_horz24
999 diamond 885
 
717 mikedld 886
  .exit:
887
	xor	eax, eax
888
	inc	eax
999 diamond 889
	pop	edi esi ebx
717 mikedld 890
	ret
891
 
892
  .error:
893
	xor	eax, eax
999 diamond 894
	pop	edi esi ebx
717 mikedld 895
	ret
896
endp
897
 
783 mikedld 898
;;================================================================================================;;
1079 diamond 899
proc img.flip _img, _flip_kind ;//////////////////////////////////////////////////////////////////;;
783 mikedld 900
;;------------------------------------------------------------------------------------------------;;
1079 diamond 901
;? Flip all layers of image                                                                       ;;
783 mikedld 902
;;------------------------------------------------------------------------------------------------;;
903
;> _img = pointer to image                                                                        ;;
1079 diamond 904
;> _flip_kind = one of FLIP_* constants                                                           ;;
905
;;------------------------------------------------------------------------------------------------;;
906
;< eax = false / true                                                                             ;;
907
;;================================================================================================;;
908
	push	1
909
	mov	ebx, [_img]
910
@@:
911
	mov	eax, [ebx + Image.Previous]
912
	test	eax, eax
913
	jz	.loop
914
	mov	ebx, eax
915
	jmp	@b
916
.loop:
917
	stdcall	img.flip.layer, ebx, [_flip_kind]
918
	test	eax, eax
919
	jnz	@f
920
	mov	byte [esp], 0
921
@@:
922
	mov	ebx, [ebx + Image.Next]
923
	test	ebx, ebx
924
	jnz	.loop
925
	pop	eax
926
	ret
927
endp
928
 
929
;;================================================================================================;;
930
proc img.rotate.layer _img, _rotate_kind ;////////////////////////////////////////////////////////;;
931
;;------------------------------------------------------------------------------------------------;;
932
;? Rotate image layer                                                                             ;;
933
;;------------------------------------------------------------------------------------------------;;
934
;> _img = pointer to image                                                                        ;;
783 mikedld 935
;> _rotate_kind = one of ROTATE_* constants                                                       ;;
936
;;------------------------------------------------------------------------------------------------;;
937
;< eax = false / true                                                                             ;;
938
;;================================================================================================;;
939
locals
940
  scanline_len_old    dd ?
941
  scanline_len_new    dd ?
942
  scanline_pixels_new dd ?
943
  line_buffer	      dd ?
944
  pixels_ptr	      dd ?
945
endl
717 mikedld 946
 
783 mikedld 947
	mov	[line_buffer], 0
948
 
949
	push	ebx esi edi
999 diamond 950
	mov	ebx, [_img]
951
	stdcall img._.validate, ebx
783 mikedld 952
	or	eax, eax
953
	jnz	.error
954
 
955
	cmp	[_rotate_kind], ROTATE_90_CCW
956
	je	.rotate_ccw_low
957
	cmp	[_rotate_kind], ROTATE_90_CW
958
	je	.rotate_cw_low
959
	cmp	[_rotate_kind], ROTATE_180
960
	je	.flip
961
	jmp	.exit
962
 
963
  .rotate_ccw_low:
964
	mov	eax, [ebx + Image.Height]
965
	mov	[scanline_pixels_new], eax
999 diamond 966
	call	img._.get_scanline_len
783 mikedld 967
	mov	[scanline_len_new], eax
968
 
969
	invoke	mem.alloc, eax
970
	or	eax, eax
971
	jz	.error
972
	mov	[line_buffer], eax
973
 
999 diamond 974
	mov	eax, [ebx + Image.Width]
975
	mov	ecx, eax
976
	call	img._.get_scanline_len
783 mikedld 977
	mov	[scanline_len_old], eax
978
 
979
	mov	eax, [scanline_len_new]
980
	imul	eax, ecx
981
	add	eax, [ebx + Image.Data]
982
	mov	[pixels_ptr], eax
983
 
999 diamond 984
	cmp	[ebx + Image.Type], Image.bpp8
985
	jz	.rotate_ccw8
986
	cmp	[ebx + Image.Type], Image.bpp24
987
	jz	.rotate_ccw24
1079 diamond 988
	cmp	[ebx + Image.Type], Image.bpp32
989
	jz	.rotate_ccw32
999 diamond 990
 
1079 diamond 991
  .next_column_ccw_low1x:
992
	dec	ecx
993
	js	.exchange_dims
994
	push	ecx
995
 
996
	mov	edx, [scanline_len_old]
997
	add	[scanline_len_old], -2
998
 
999
	mov	ecx, [scanline_pixels_new]
1000
	mov	esi, [ebx + Image.Data]
1001
	mov	edi, [line_buffer]
1002
    @@: mov	ax, [esi]
1003
	mov	[edi], ax
1004
	add	esi, edx
1005
	add	edi, 2
1006
	sub	ecx, 1
1007
	jnz	@b
1008
 
1009
	mov	eax, [scanline_pixels_new]
1010
	mov	edi, [ebx + Image.Data]
1011
	lea	esi, [edi + 2]
1012
	mov	edx, [scanline_len_old]
1013
    @@: mov	ecx, edx
1014
	shr	ecx, 2
1015
	rep	movsd
1016
	mov	ecx, edx
1017
	and	ecx, 3
1018
	rep	movsb
1019
	add	esi, 1
1020
	sub	eax, 1
1021
	jnz	@b
1022
 
1023
	mov	eax, [scanline_len_new]
1024
	sub	[pixels_ptr], eax
1025
	mov	ecx, [scanline_pixels_new]
1026
	mov	esi, [line_buffer]
1027
	mov	edi, [pixels_ptr]
1028
	mov	edx, ecx
1029
	shr	ecx, 2
1030
	rep	movsd
1031
	mov	ecx, edx
1032
	and	ecx, 3
1033
	rep	movsb
1034
 
1035
	pop	ecx
1036
	jmp	.next_column_ccw_low1x
1037
 
1038
.rotate_ccw32:
783 mikedld 1039
  .next_column_ccw_low:
1040
	dec	ecx
999 diamond 1041
	js	.exchange_dims
783 mikedld 1042
	push	ecx
1043
 
1044
	mov	edx, [scanline_len_old]
1045
	add	[scanline_len_old], -4
1046
 
1047
	mov	ecx, [scanline_pixels_new]
1048
	mov	esi, [ebx + Image.Data]
1049
	mov	edi, [line_buffer]
1050
    @@: mov	eax, [esi]
1051
	stosd
1052
	add	esi, edx
1053
	dec	ecx
1054
	jnz	@b
1055
 
1056
	mov	eax, [scanline_pixels_new]
1057
	mov	edi, [ebx + Image.Data]
1058
	lea	esi, [edi + 4]
1059
	mov	edx, [scanline_len_old]
1060
	shr	edx, 2
1061
    @@: mov	ecx, edx
1062
	rep	movsd
1063
	add	esi, 4
1064
	dec	eax
1065
	jnz	@b
1066
 
1067
	mov	eax, [scanline_len_new]
1068
	sub	[pixels_ptr], eax
1069
	mov	ecx, [scanline_pixels_new]
1070
	mov	esi, [line_buffer]
1071
	mov	edi, [pixels_ptr]
1072
	rep	movsd
1073
 
1074
	pop	ecx
1075
	jmp	.next_column_ccw_low
1076
 
999 diamond 1077
.rotate_ccw8:
1078
  .next_column_ccw_low8:
1079
	dec	ecx
1080
	js	.exchange_dims
1081
	push	ecx
1082
 
1083
	mov	edx, [scanline_len_old]
1084
	add	[scanline_len_old], -1
1085
 
1086
	mov	ecx, [scanline_pixels_new]
1087
	mov	esi, [ebx + Image.Data]
1088
	mov	edi, [line_buffer]
1089
    @@: mov	al, [esi]
1090
	mov	[edi], al
1091
	add	esi, edx
1092
	add	edi, 1
1093
	sub	ecx, 1
1094
	jnz	@b
1095
 
1096
	mov	eax, [scanline_pixels_new]
1097
	mov	edi, [ebx + Image.Data]
1098
	lea	esi, [edi + 1]
1099
	mov	edx, [scanline_len_old]
1100
    @@: mov	ecx, edx
1101
	shr	ecx, 2
1102
	rep	movsd
1103
	mov	ecx, edx
1104
	and	ecx, 3
1105
	rep	movsb
1106
	add	esi, 1
1107
	sub	eax, 1
1108
	jnz	@b
1109
 
1110
	mov	eax, [scanline_len_new]
1111
	sub	[pixels_ptr], eax
1112
	mov	ecx, [scanline_pixels_new]
1113
	mov	esi, [line_buffer]
1114
	mov	edi, [pixels_ptr]
1115
	mov	edx, ecx
1116
	shr	ecx, 2
1117
	rep	movsd
1118
	mov	ecx, edx
1119
	and	ecx, 3
1120
	rep	movsb
1121
 
1122
	pop	ecx
1123
	jmp	.next_column_ccw_low8
1124
 
1125
.rotate_ccw24:
1126
  .next_column_ccw_low24:
1127
	dec	ecx
1128
	js	.exchange_dims
1129
	push	ecx
1130
 
1131
	mov	edx, [scanline_len_old]
1132
	add	[scanline_len_old], -3
1133
 
1134
	mov	ecx, [scanline_pixels_new]
1135
	mov	esi, [ebx + Image.Data]
1136
	mov	edi, [line_buffer]
1137
    @@: mov	al, [esi]
1138
	mov	[edi], al
1139
	mov	al, [esi+1]
1140
	mov	[edi+1], al
1141
	mov	al, [esi+2]
1142
	mov	[edi+2], al
1143
	add	esi, edx
1144
	add	edi, 3
1145
	sub	ecx, 1
1146
	jnz	@b
1147
 
1148
	mov	eax, [scanline_pixels_new]
1149
	mov	edi, [ebx + Image.Data]
1150
	lea	esi, [edi + 3]
1151
	mov	edx, [scanline_len_old]
1152
    @@: mov	ecx, edx
1153
	shr	ecx, 2
1154
	rep	movsd
1155
	mov	ecx, edx
1156
	and	ecx, 3
1157
	rep	movsb
1158
	add	esi, 3
1159
	sub	eax, 1
1160
	jnz	@b
1161
 
1162
	mov	eax, [scanline_len_new]
1163
	sub	[pixels_ptr], eax
1164
	mov	ecx, eax
1165
	mov	esi, [line_buffer]
1166
	mov	edi, [pixels_ptr]
1167
	shr	ecx, 2
1168
	rep	movsd
1169
	mov	ecx, eax
1170
	and	ecx, 3
1171
	rep	movsb
1172
 
1173
	pop	ecx
1174
	jmp	.next_column_ccw_low24
1175
 
783 mikedld 1176
  .rotate_cw_low:
1177
	mov	eax, [ebx + Image.Height]
1178
	mov	[scanline_pixels_new], eax
999 diamond 1179
	call	img._.get_scanline_len
783 mikedld 1180
	mov	[scanline_len_new], eax
1181
 
1182
	invoke	mem.alloc, eax
1183
	or	eax, eax
1184
	jz	.error
1185
	mov	[line_buffer], eax
1186
 
999 diamond 1187
	mov	eax, [ebx + Image.Width]
1188
	mov	ecx, eax
1189
	call	img._.get_scanline_len
783 mikedld 1190
	mov	[scanline_len_old], eax
1191
 
1192
	mov	eax, [scanline_len_new]
1193
	imul	eax, ecx
1194
	add	eax, [ebx + Image.Data]
1195
	mov	[pixels_ptr], eax
1196
 
999 diamond 1197
	cmp	[ebx + Image.Type], Image.bpp8
1198
	jz	.rotate_cw8
1199
	cmp	[ebx + Image.Type], Image.bpp24
1200
	jz	.rotate_cw24
1079 diamond 1201
	cmp	[ebx + Image.Type], Image.bpp32
1202
	jz	.rotate_cw32
999 diamond 1203
 
1079 diamond 1204
  .next_column_cw_low1x:
1205
	dec	ecx
1206
	js	.exchange_dims
1207
	push	ecx
1208
 
1209
	mov	edx, [scanline_len_old]
1210
	add	[scanline_len_old], -2
1211
 
1212
	mov	ecx, [scanline_pixels_new]
1213
	mov	esi, [pixels_ptr]
1214
	add	esi, -2
1215
	mov	edi, [line_buffer]
1216
    @@: mov	ax, [esi]
1217
	mov	[edi], ax
1218
	sub	esi, edx
1219
	add	edi, 2
1220
	sub	ecx, 1
1221
	jnz	@b
1222
 
1223
	mov	eax, [scanline_pixels_new]
1224
	dec	eax
1225
	mov	edi, [ebx + Image.Data]
1226
	add	edi, [scanline_len_old]
1227
	lea	esi, [edi + 2]
1228
	mov	edx, [scanline_len_old]
1229
    @@: mov	ecx, edx
1230
	shr	ecx, 2
1231
	rep	movsd
1232
	mov	ecx, edx
1233
	and	ecx, 3
1234
	rep	movsb
1235
	add	esi, 3
1236
	sub	eax, 1
1237
	jnz	@b
1238
 
1239
	mov	eax, [scanline_len_new]
1240
	sub	[pixels_ptr], eax
1241
	mov	ecx, eax
1242
	mov	esi, [line_buffer]
1243
	mov	edi, [pixels_ptr]
1244
	shr	ecx, 2
1245
	rep	movsd
1246
	mov	ecx, eax
1247
	and	ecx, 3
1248
	rep	movsb
1249
 
1250
	pop	ecx
1251
	jmp	.next_column_cw_low1x
1252
 
1253
.rotate_cw32:
783 mikedld 1254
  .next_column_cw_low:
1255
	dec	ecx
1256
	js	.exchange_dims
1257
	push	ecx
1258
 
1259
	mov	edx, [scanline_len_old]
1260
	add	[scanline_len_old], -4
1261
 
1262
	mov	ecx, [scanline_pixels_new]
1263
	mov	esi, [pixels_ptr]
1264
	add	esi, -4
1265
	mov	edi, [line_buffer]
1266
    @@: mov	eax, [esi]
1267
	stosd
1268
	sub	esi, edx
1269
	dec	ecx
1270
	jnz	@b
1271
 
1272
	mov	eax, [scanline_pixels_new]
1273
	dec	eax
1274
	mov	edi, [ebx + Image.Data]
1275
	add	edi, [scanline_len_old]
1276
	lea	esi, [edi + 4]
1277
	mov	edx, [scanline_len_old]
1278
	shr	edx, 2
1279
    @@: mov	ecx, edx
1280
	rep	movsd
1281
	add	esi, 4
1282
	dec	eax
1283
	jnz	@b
1284
 
1285
	mov	eax, [scanline_len_new]
1286
	sub	[pixels_ptr], eax
1287
	mov	ecx, [scanline_pixels_new]
1288
	mov	esi, [line_buffer]
1289
	mov	edi, [pixels_ptr]
1290
	rep	movsd
1291
 
1292
	pop	ecx
1293
	jmp	.next_column_cw_low
1294
 
999 diamond 1295
.rotate_cw8:
1296
  .next_column_cw_low8:
1297
	dec	ecx
1298
	js	.exchange_dims
1299
	push	ecx
1300
 
1301
	mov	edx, [scanline_len_old]
1302
	add	[scanline_len_old], -1
1303
 
1304
	mov	ecx, [scanline_pixels_new]
1305
	mov	esi, [pixels_ptr]
1306
	add	esi, -1
1307
	mov	edi, [line_buffer]
1308
    @@: mov	al, [esi]
1309
	mov	[edi], al
1310
	sub	esi, edx
1311
	add	edi, 1
1312
	sub	ecx, 1
1313
	jnz	@b
1314
 
1315
	mov	eax, [scanline_pixels_new]
1316
	dec	eax
1317
	mov	edi, [ebx + Image.Data]
1318
	add	edi, [scanline_len_old]
1319
	lea	esi, [edi + 1]
1320
	mov	edx, [scanline_len_old]
1321
    @@: mov	ecx, edx
1322
	shr	ecx, 2
1323
	rep	movsd
1324
	mov	ecx, edx
1325
	and	ecx, 3
1326
	rep	movsb
1327
	add	esi, 1
1328
	sub	eax, 1
1329
	jnz	@b
1330
 
1331
	mov	eax, [scanline_len_new]
1332
	sub	[pixels_ptr], eax
1333
	mov	ecx, eax
1334
	mov	esi, [line_buffer]
1335
	mov	edi, [pixels_ptr]
1336
	shr	ecx, 2
1337
	rep	movsd
1338
	mov	ecx, eax
1339
	and	ecx, 3
1340
	rep	movsb
1341
 
1342
	pop	ecx
1343
	jmp	.next_column_cw_low8
1344
 
1345
.rotate_cw24:
1346
  .next_column_cw_low24:
1347
	dec	ecx
1348
	js	.exchange_dims
1349
	push	ecx
1350
 
1351
	mov	edx, [scanline_len_old]
1352
	add	[scanline_len_old], -3
1353
 
1354
	mov	ecx, [scanline_pixels_new]
1355
	mov	esi, [pixels_ptr]
1356
	add	esi, -3
1357
	mov	edi, [line_buffer]
1358
    @@: mov	al, [esi]
1359
	mov	[edi], al
1360
	mov	al, [esi+1]
1361
	mov	[edi+1], al
1362
	mov	al, [esi+2]
1363
	mov	[edi+2], al
1364
	sub	esi, edx
1365
	add	edi, 3
1366
	sub	ecx, 1
1367
	jnz	@b
1368
 
1369
	mov	eax, [scanline_pixels_new]
1370
	dec	eax
1371
	mov	edi, [ebx + Image.Data]
1372
	add	edi, [scanline_len_old]
1373
	lea	esi, [edi + 3]
1374
	mov	edx, [scanline_len_old]
1375
    @@: mov	ecx, edx
1376
	shr	ecx, 2
1377
	rep	movsd
1378
	mov	ecx, edx
1379
	and	ecx, 3
1380
	rep	movsb
1381
	add	esi, 3
1382
	sub	eax, 1
1383
	jnz	@b
1384
 
1385
	mov	eax, [scanline_len_new]
1386
	sub	[pixels_ptr], eax
1387
	mov	ecx, eax
1388
	mov	esi, [line_buffer]
1389
	mov	edi, [pixels_ptr]
1390
	shr	ecx, 2
1391
	rep	movsd
1392
	mov	ecx, eax
1393
	and	ecx, 3
1394
	rep	movsb
1395
 
1396
	pop	ecx
1397
	jmp	.next_column_cw_low24
1398
 
783 mikedld 1399
  .flip:
1400
	jmp	.exit
1401
 
1402
  .exchange_dims:
1403
	push	[ebx + Image.Width] [ebx + Image.Height]
1404
	pop	[ebx + Image.Width] [ebx + Image.Height]
1405
 
1406
  .exit:
1407
	invoke	mem.free, [line_buffer]
1408
	xor	eax, eax
1409
	inc	eax
1410
	pop	edi esi ebx
1411
	ret
1412
 
1413
  .error:
1414
	invoke	mem.free, [line_buffer]
1415
	xor	eax, eax
1416
	pop	edi esi ebx
1417
	ret
1418
endp
1419
 
1079 diamond 1420
;;================================================================================================;;
1421
proc img.rotate _img, _rotate_kind ;//////////////////////////////////////////////////////////////;;
1422
;;------------------------------------------------------------------------------------------------;;
1423
;? Rotate all layers of image                                                                     ;;
1424
;;------------------------------------------------------------------------------------------------;;
1425
;> _img = pointer to image                                                                        ;;
1426
;> _rotate_kind = one of ROTATE_* constants                                                       ;;
1427
;;------------------------------------------------------------------------------------------------;;
1428
;< eax = false / true                                                                             ;;
1429
;;================================================================================================;;
1430
	push	1
1431
	mov	ebx, [_img]
1432
@@:
1433
	mov	eax, [ebx + Image.Previous]
1434
	test	eax, eax
1435
	jz	.loop
1436
	mov	ebx, eax
1437
	jmp	@b
1438
.loop:
1439
	stdcall	img.rotate.layer, ebx, [_rotate_kind]
1440
	test	eax, eax
1441
	jnz	@f
1442
	mov	byte [esp], 0
1443
@@:
1444
	mov	ebx, [ebx + Image.Next]
1445
	test	ebx, ebx
1446
	jnz	.loop
1447
	pop	eax
1448
	ret
1449
endp
783 mikedld 1450
 
717 mikedld 1451
;;================================================================================================;;
1079 diamond 1452
proc img.draw _img, _x, _y, _width, _height, _xpos, _ypos ;///////////////////////////////////////;;
1453
;;------------------------------------------------------------------------------------------------;;
1454
;? Draw image in the window                                                                       ;;
1455
;;------------------------------------------------------------------------------------------------;;
1456
;> _img = pointer to image                                                                        ;;
1457
;>_x = x-coordinate in the window                                                                 ;;
1458
;>_y = y-coordinate in the window                                                                 ;;
1459
;>_width = maximum width to draw                                                                  ;;
1460
;>_height = maximum height to draw                                                                ;;
1461
;>_xpos = offset in image by x-axis                                                               ;;
1462
;>_ypos = offset in image by y-axis                                                               ;;
1463
;;------------------------------------------------------------------------------------------------;;
1464
;< no return value                                                                                ;;
1465
;;================================================================================================;;
1466
	push	ebx esi edi
1467
	mov	ebx, [_img]
1468
	stdcall	img._.validate, ebx
1469
	test	eax, eax
1470
	jnz	.done
1471
	mov	ecx, [ebx + Image.Width]
1472
	sub	ecx, [_xpos]
1473
	jbe	.done
1474
	cmp	ecx, [_width]
1475
	jb	@f
1476
	mov	ecx, [_width]
1477
@@:
1478
	mov	edx, [ebx + Image.Height]
1479
	sub	edx, [_ypos]
1480
	jbe	.done
1481
	cmp	edx, [_height]
1482
	jb	@f
1483
	mov	edx, [_height]
1484
@@:
1485
	mov	eax, [ebx + Image.Width]
1486
	sub	eax, ecx
1487
	call	img._.get_scanline_len
1488
	shl	ecx, 16
1489
	add	ecx, edx
1490
	mov	edx, [_x - 2]
1491
	mov	dx, word [_y]
1492
	mov	esi, [ebx + Image.Type]
1493
	mov	esi, [type2bpp + (esi-1)*4]
1494
	mov	edi, [ebx + Image.Palette]
1495
	mov	ebx, [ebx + Image.Data]
1496
	push	ebp
1497
	push	65
1498
	pop	ebp
1499
	xchg	eax, ebp
1500
	int	40h
1501
	pop	ebp
1502
.done:
1503
	pop	edi esi ebx
1504
	ret
1505
endp
1506
 
1507
;;================================================================================================;;
717 mikedld 1508
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1509
;;================================================================================================;;
1510
;! Below are private procs you should never call directly from your code                          ;;
1511
;;================================================================================================;;
1512
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1513
;;================================================================================================;;
1514
 
1515
 
1516
;;================================================================================================;;
1517
proc img._.validate, _img ;///////////////////////////////////////////////////////////////////////;;
1518
;;------------------------------------------------------------------------------------------------;;
1519
;? --- TBD ---                                                                                    ;;
1520
;;------------------------------------------------------------------------------------------------;;
1521
;> --- TBD ---                                                                                    ;;
1522
;;------------------------------------------------------------------------------------------------;;
1523
;< --- TBD ---                                                                                    ;;
1524
;;================================================================================================;;
1525
	xor	eax, eax
1526
	ret
1527
endp
1528
 
1529
;;================================================================================================;;
1530
proc img._.new ;//////////////////////////////////////////////////////////////////////////////////;;
1531
;;------------------------------------------------------------------------------------------------;;
1532
;? --- TBD ---                                                                                    ;;
1533
;;------------------------------------------------------------------------------------------------;;
1534
;> --- TBD ---                                                                                    ;;
1535
;;------------------------------------------------------------------------------------------------;;
1536
;< eax = 0 / pointer to image                                                                     ;;
1537
;;================================================================================================;;
1538
	invoke	mem.alloc, sizeof.Image
999 diamond 1539
	test	eax, eax
1540
	jz	@f
1541
	push	ecx
1542
	xor	ecx, ecx
1543
	mov	[eax + Image.Data], ecx
1544
	mov	[eax + Image.Type], ecx
1079 diamond 1545
	mov	[eax + Image.Flags], ecx
999 diamond 1546
	mov	[eax + Image.Extended], ecx
1547
	mov	[eax + Image.Previous], ecx
1548
	mov	[eax + Image.Next], ecx
1549
	pop	ecx
1550
@@:
717 mikedld 1551
	ret
1552
endp
1553
 
1554
;;================================================================================================;;
1555
proc img._.delete _img ;//////////////////////////////////////////////////////////////////////////;;
1556
;;------------------------------------------------------------------------------------------------;;
1557
;? --- TBD ---                                                                                    ;;
1558
;;------------------------------------------------------------------------------------------------;;
1559
;> --- TBD ---                                                                                    ;;
1560
;;------------------------------------------------------------------------------------------------;;
1561
;< eax = false / true                                                                             ;;
1562
;;================================================================================================;;
1563
	push	edx
1564
	mov	edx, [_img]
1565
	cmp	[edx + Image.Data], 0
1566
	je	@f
1567
	invoke	mem.free, [edx + Image.Data]
1568
    @@: cmp	[edx + Image.Extended], 0
1569
	je	@f
1570
	invoke	mem.free, [edx + Image.Extended]
1571
    @@: invoke	mem.free, edx
1572
	pop	edx
1573
	ret
1574
endp
1575
 
783 mikedld 1576
;;================================================================================================;;
1577
proc img._.resize_data _img, _width, _height ;////////////////////////////////////////////////////;;
1578
;;------------------------------------------------------------------------------------------------;;
1579
;? --- TBD ---                                                                                    ;;
1580
;;------------------------------------------------------------------------------------------------;;
1581
;> --- TBD ---                                                                                    ;;
1582
;;------------------------------------------------------------------------------------------------;;
1583
;< --- TBD ---                                                                                    ;;
1584
;;================================================================================================;;
999 diamond 1585
	push	ebx esi
783 mikedld 1586
	mov	ebx, [_img]
1587
	mov	eax, [_height]
999 diamond 1588
; our memory is limited, [_width]*[_height] must not overflow
1589
; image with width or height greater than 65535 is most likely bogus
1590
	cmp	word [_width+2], 0
1591
	jnz	.error
1592
	cmp	word [_height+2], 0
1593
	jnz	.error
783 mikedld 1594
	imul	eax, [_width]
999 diamond 1595
	test	eax, eax
1596
	jz	.error
1597
; do not allow images which require too many memory
1598
	cmp	eax, 4000000h
1599
	jae	.error
1600
	cmp	[ebx + Image.Type], Image.bpp8
1601
	jz	.bpp8
1602
	cmp	[ebx + Image.Type], Image.bpp24
1603
	jz	.bpp24
1604
.bpp32:
783 mikedld 1605
	shl	eax, 2
999 diamond 1606
	jmp	@f
1607
.bpp24:
1608
	lea	eax, [eax*3]
1609
	jmp	@f
1610
.bpp8:
1611
	add	eax, 256*4	; for palette
1612
@@:
1613
	mov	esi, eax
783 mikedld 1614
	invoke	mem.realloc, [ebx + Image.Data], eax
1615
	or	eax, eax
1616
	jz	.error
717 mikedld 1617
 
783 mikedld 1618
	mov	[ebx + Image.Data], eax
1619
	push	[_width]
1620
	pop	[ebx + Image.Width]
1621
	push	[_height]
1622
	pop	[ebx + Image.Height]
999 diamond 1623
	cmp	[ebx + Image.Type], Image.bpp8
1624
	jnz	.ret
1625
	lea	esi, [eax + esi - 256*4]
1626
	mov	[ebx + Image.Palette], esi
1627
	jmp	.ret
783 mikedld 1628
 
1629
  .error:
999 diamond 1630
	xor	eax, eax
1631
  .ret:
1632
	pop	esi ebx
783 mikedld 1633
	ret
1634
endp
1635
 
999 diamond 1636
;;================================================================================================;;
1637
img._.get_scanline_len: ;/////////////////////////////////////////////////////////////////////////;;
1638
;;------------------------------------------------------------------------------------------------;;
1639
;? --- TBD ---                                                                                    ;;
1640
;;------------------------------------------------------------------------------------------------;;
1641
;> --- TBD ---                                                                                    ;;
1642
;;------------------------------------------------------------------------------------------------;;
1643
;< --- TBD ---                                                                                    ;;
1644
;;================================================================================================;;
1645
	cmp	[ebx + Image.Type], Image.bpp8
1646
	jz	.bpp8.1
1647
	cmp	[ebx + Image.Type], Image.bpp24
1648
	jz	.bpp24.1
1079 diamond 1649
	add	eax, eax
1650
	cmp	[ebx + Image.Type], Image.bpp32
1651
	jnz	@f
1652
	add	eax, eax
999 diamond 1653
	jmp	@f
1654
.bpp24.1:
1655
	lea	eax, [eax*3]
1656
.bpp8.1:
1657
@@:
1658
	ret
783 mikedld 1659
 
999 diamond 1660
 
717 mikedld 1661
;;================================================================================================;;
1662
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1663
;;================================================================================================;;
1664
;! Below is private data you should never use directly from your code                             ;;
1665
;;================================================================================================;;
1666
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1667
;;================================================================================================;;
1668
 
1079 diamond 1669
align 4
717 mikedld 1670
img._.formats_table:
1671
  .bmp dd img.is.bmp, img.decode.bmp, img.encode.bmp
1102 diamond 1672
  .ico dd img.is.ico, img.decode.ico_cur, img.encode.ico
1673
  .cur dd img.is.cur, img.decode.ico_cur, img.encode.cur
717 mikedld 1674
  .gif dd img.is.gif, img.decode.gif, img.encode.gif
1014 diamond 1675
  .png dd img.is.png, img.decode.png, img.encode.png
999 diamond 1676
  .jpg dd img.is.jpg, img.decode.jpg, img.encode.jpg
1079 diamond 1677
  .tga dd img.is.tga, img.decode.tga, img.encode.tga
1678
  .z80 dd img.is.z80, img.decode.z80, img.encode.z80 ;this must be the last entry as there are no
1679
  ;signatures in z80 screens at all
717 mikedld 1680
       dd 0
1681
 
1079 diamond 1682
align 4
1683
type2bpp	dd	8, 24, 32, 15, 16
1684
img._.do_rgb.handlers:
1685
	dd	img._.do_rgb.bpp8
1686
	dd	img._.do_rgb.bpp24
1687
	dd	img._.do_rgb.bpp32
1688
	dd	img._.do_rgb.bpp15.amd	; can be overwritten in lib_init
1689
	dd	img._.do_rgb.bpp16.amd	; can be overwritten in lib_init
717 mikedld 1690
 
1079 diamond 1691
img.flip.layer.handlers_horz:
1692
	dd	img.flip.layer.bpp8_horz
1693
	dd	img.flip.layer.bpp24_horz
1694
	dd	img.flip.layer.bpp32_horz
1695
	dd	img.flip.layer.bpp1x_horz
1696
	dd	img.flip.layer.bpp1x_horz
1697
 
717 mikedld 1698
;;================================================================================================;;
1699
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1700
;;================================================================================================;;
1701
;! Exported functions section                                                                     ;;
1702
;;================================================================================================;;
1703
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1704
;;================================================================================================;;
1705
 
1706
 
999 diamond 1707
align 4
717 mikedld 1708
@EXPORT:
1709
 
1710
export					      \
1711
	lib_init	, 'lib_init'	    , \
1102 diamond 1712
	0x00050005	, 'version'	    , \
1713
	img.is_img	, 'img_is_img'	    , \
1714
	img.info	, 'img_info'	    , \
1715
	img.from_file	, 'img_from_file'   , \
1716
	img.to_file	, 'img_to_file'     , \
1717
	img.from_rgb	, 'img_from_rgb'    , \
1718
	img.to_rgb	, 'img_to_rgb'	    , \
1719
	img.to_rgb2	, 'img_to_rgb2'     , \
1720
	img.decode	, 'img_decode'	    , \
1721
	img.encode	, 'img_encode'	    , \
1722
	img.create	, 'img_create'	    , \
1723
	img.destroy	, 'img_destroy'     , \
1724
	img.destroy.layer, 'img_destroy_layer', \
1725
	img.count	, 'img_count'	    , \
1726
	img.lock_bits	, 'img_lock_bits'   , \
1727
	img.unlock_bits , 'img_unlock_bits' , \
1728
	img.flip	, 'img_flip'	    , \
1729
	img.flip.layer  , 'img_flip_layer'  , \
1730
	img.rotate	, 'img_rotate'      , \
1731
	img.rotate.layer, 'img_rotate_layer', \
1732
	img.draw        , 'img_draw'
999 diamond 1733
 
1014 diamond 1734
; import from deflate unpacker
1735
; is initialized only when PNG loading is requested
1736
align 4
1737
@IMPORT:
1738
 
1102 diamond 1739
library archiver, 'archiver.obj'
1740
import	archiver, \
1014 diamond 1741
	deflate_unpack2, 'deflate_unpack2'
1742
 
1079 diamond 1743
align 4
1014 diamond 1744
; mutex for unpacker loading
1745
deflate_loader_mutex	dd	0
1746
 
1079 diamond 1747
; default palette for GIF - b&w
1748
gif_default_palette:
1749
	db	0, 0, 0
1750
	db	0xFF, 0xFF, 0xFF
1751
 
999 diamond 1752
section '.data' data readable writable align 16
1753
; uninitialized data - global constant tables
1079 diamond 1754
mem.alloc   dd ?
1755
mem.free    dd ?
1756
mem.realloc dd ?
1757
dll.load    dd ?
999 diamond 1758
 
1759
; data for YCbCr -> RGB translation
1760
color_table_1		rd	256
1761
color_table_2		rd	256
1762
color_table_3		rd	256
1763
color_table_4		rd	256