Subversion Repositories Kolibri OS

Rev

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