Subversion Repositories Kolibri OS

Rev

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