Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
8497 dunkaist 1
;;============================================================================;;
2
;;//// libimg.asm //// (c) mike.dld, 2007-2008                                ;;
3
;;                //// (c) diamond, 2009,                                     ;;
4
;;                //// (c) dunkaist, 2011-2020                                ;;
5
;;============================================================================;;
6
;;                                                                            ;;
7
;; This file is part of Common development libraries (Libs-Dev).              ;;
8
;;                                                                            ;;
9
;; Libs-Dev is free software: you can redistribute it and/or modify it under  ;;
10
;; the terms of the GNU Lesser General Public License as published by the     ;;
11
;; Free Software Foundation, either version 2.1 of the License, or (at your   ;;
12
;; option) any later version.                                                 ;;
13
;;                                                                            ;;
14
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT    ;;
15
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or      ;;
16
;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public        ;;
17
;; License for more details.                                                  ;;
18
;;                                                                            ;;
19
;; You should have received a copy of the GNU Lesser General Public License   ;;
20
;; along with Libs-Dev. If not, see .           ;;
21
;;                                                                            ;;
22
;;============================================================================;;
6807 dunkaist 23
 
24
 
25
format MS COFF
26
 
27
public @EXPORT as 'EXPORTS'
28
 
8341 dunkaist 29
include 'struct.inc'
30
include 'proc32.inc'
31
include 'macros.inc'
32
include 'config.inc'
33
include 'debug-fdo.inc'
7105 dunkaist 34
__DEBUG__ = 0
35
__DEBUG_LEVEL__ = 1
8341 dunkaist 36
include 'libio.inc'
6807 dunkaist 37
purge section,mov,add,sub
38
 
39
include 'libimg.inc'
40
 
41
section '.flat' code readable align 16
42
 
43
include 'bmp/bmp.asm'
44
include 'gif/gif.asm'
45
include 'jpeg/jpeg.asm'
46
include 'png/png.asm'
47
include 'tga/tga.asm'
48
include 'z80/z80.asm'
49
include 'ico_cur/ico_cur.asm'
50
include 'pcx/pcx.asm'
51
include 'xcf/xcf.asm'
52
include 'tiff/tiff.asm'
53
include 'pnm/pnm.asm'
54
include 'wbmp/wbmp.asm'
55
include 'xbm/xbm.asm'
56
 
57
include 'scale.asm'
58
include 'convert.asm'
59
 
8341 dunkaist 60
COMPOSITE_MODE equ MMX
61
; MMX | pretty fast and compatible
62
; SSE | a bit faster, but may be unsupported by some CPUs
63
include 'blend.asm'
64
 
8497 dunkaist 65
;;============================================================================;;
66
proc lib_init ;///////////////////////////////////////////////////////////////;;
67
;;----------------------------------------------------------------------------;;
68
;? Library entry point (called after library load)                            ;;
69
;;----------------------------------------------------------------------------;;
70
;> eax = pointer to memory allocation routine                                 ;;
71
;> ebx = pointer to memory freeing routine                                    ;;
72
;> ecx = pointer to memory reallocation routine                               ;;
73
;> edx = pointer to library loading routine                                   ;;
74
;;----------------------------------------------------------------------------;;
75
;< eax = 1 (fail) / 0 (ok) (library initialization result)                    ;;
76
;;============================================================================;;
77
        mov     [mem.alloc], eax
78
        mov     [mem.free], ebx
79
        mov     [mem.realloc], ecx
80
        mov     [dll.load], edx
6807 dunkaist 81
 
8497 dunkaist 82
        or      edx, edx
83
        jz      @f
84
        invoke  dll.load, @IMPORT
85
@@:
6807 dunkaist 86
 
8497 dunkaist 87
        call    img.initialize.jpeg
6807 dunkaist 88
 
8497 dunkaist 89
        xor     eax, eax
90
        cpuid
91
        cmp     ecx, 'ntel'
92
        jnz     @f
93
        mov     dword [img._.do_rgb.handlers + (Image.bpp15-1)*4], img._.do_rgb.bpp15.intel
94
        mov     dword [img._.do_rgb.handlers + (Image.bpp16-1)*4], img._.do_rgb.bpp16.intel
95
@@:
6807 dunkaist 96
 
8497 dunkaist 97
.ok:
98
        xor     eax, eax
99
        ret
6807 dunkaist 100
endp
101
 
8497 dunkaist 102
;;============================================================================;;
103
proc img.is_img _data, _length ;//////////////////////////////////////////////;;
104
;;----------------------------------------------------------------------------;;
105
;? --- TBD ---                                                                ;;
106
;;----------------------------------------------------------------------------;;
107
;> --- TBD ---                                                                ;;
108
;;----------------------------------------------------------------------------;;
109
;< --- TBD ---                                                                ;;
110
;;============================================================================;;
111
        push    ebx
112
        mov     ebx, img.formats_table
113
@@:
114
        stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
115
        or      eax, eax
116
        jnz     @f
117
        add     ebx, sizeof.FormatsTableEntry
118
        cmp     dword[ebx], 0
119
        jnz     @b
120
        xor     eax, eax
121
@@:
122
        pop     ebx
123
        ret
6807 dunkaist 124
endp
125
 
8497 dunkaist 126
;;============================================================================;;
127
proc img.info _data, _length ;////////////////////////////////////////////////;;
128
;;----------------------------------------------------------------------------;;
129
;? --- TBD ---                                                                ;;
130
;;----------------------------------------------------------------------------;;
131
;> --- TBD ---                                                                ;;
132
;;----------------------------------------------------------------------------;;
133
;< --- TBD ---                                                                ;;
134
;;============================================================================;;
135
        xor     eax, eax
136
        ret
6807 dunkaist 137
endp
138
 
8497 dunkaist 139
;;============================================================================;;
140
proc img.from_file _filename ;////////////////////////////////////////////////;;
141
;;----------------------------------------------------------------------------;;
142
;? load file from disk and decode it                                          ;;
143
;;----------------------------------------------------------------------------;;
144
;> [_filename] = file name as passed to libio                                 ;;
145
;;----------------------------------------------------------------------------;;
146
;< eax = 0 / pointer to image                                                 ;;
147
;;============================================================================;;
7105 dunkaist 148
locals
8497 dunkaist 149
        fd              dd ?
150
        img_data_len    dd ?
151
        img_data        dd ?    ; raw bytes
152
        img             dd ?    ; Image pointer
7105 dunkaist 153
endl
8497 dunkaist 154
        push    ebx
155
        mov     [img], 0
156
        invoke  file.open, [_filename], O_READ
157
        mov     [fd], eax
158
        test    eax, eax
159
        jz      .exit
160
        invoke  file.size, [_filename]
161
        test    eax, eax
162
        jnz     .exit_close
163
        mov     [img_data_len], ebx
164
        invoke  mem.alloc, ebx
165
        test    eax, eax
166
        jz      .exit_close
167
        mov     [img_data], eax
168
        invoke  file.read, [fd], eax, [img_data_len]
169
        cmp     eax, -1
170
        jz      .exit_free_close
171
        cmp     eax, [img_data_len]
172
        jnz     .exit_free_close
173
        stdcall img.decode, [img_data], [img_data_len], 0
174
        test    eax, eax
175
        jz      .exit_free_close
176
        mov     [img], eax
177
.exit_free_close:
178
        invoke  mem.free, [img_data]
179
.exit_close:
180
        invoke  file.close, [fd]
181
        mov     eax, [img]
182
.exit:
183
        pop     ebx
184
        ret
6807 dunkaist 185
endp
186
 
8497 dunkaist 187
;;============================================================================;;
188
proc img.to_file _img, _filename ;////////////////////////////////////////////;;
189
;;----------------------------------------------------------------------------;;
190
;? --- TBD ---                                                                ;;
191
;;----------------------------------------------------------------------------;;
192
;> --- TBD ---                                                                ;;
193
;;----------------------------------------------------------------------------;;
194
;< eax = false / true                                                         ;;
195
;;============================================================================;;
196
        xor     eax, eax
197
        ret
6807 dunkaist 198
endp
199
 
8497 dunkaist 200
;;============================================================================;;
201
proc img.from_rgb _rgb_data ;/////////////////////////////////////////////////;;
202
;;----------------------------------------------------------------------------;;
203
;? --- TBD ---                                                                ;;
204
;;----------------------------------------------------------------------------;;
205
;> --- TBD ---                                                                ;;
206
;;----------------------------------------------------------------------------;;
207
;< eax = 0 / pointer to image                                                 ;;
208
;;============================================================================;;
209
        xor     eax, eax
210
        ret
6807 dunkaist 211
endp
212
 
8497 dunkaist 213
;;============================================================================;;
214
proc img.to_rgb2 _img, _out ;/////////////////////////////////////////////////;;
215
;;----------------------------------------------------------------------------;;
216
;? decodes image data into RGB triplets and stores them where [_out] points to;;
217
;;----------------------------------------------------------------------------;;
218
;> [_img] = pointer to source image                                           ;;
219
;> [_out] = where to store RGB triplets                                       ;;
220
;;----------------------------------------------------------------------------;;
221
;< none                                                                       ;;
222
;;============================================================================;;
223
        push    esi edi
224
        mov     esi, [_img]
225
        stdcall img._.validate, esi
226
        or      eax, eax
227
        jnz     .ret
228
        mov     edi, [_out]
229
        call    img._.do_rgb
6807 dunkaist 230
.ret:
8497 dunkaist 231
        pop     edi esi
232
        ret
6807 dunkaist 233
endp
234
 
8497 dunkaist 235
;;============================================================================;;
236
proc img.to_rgb _img ;////////////////////////////////////////////////////////;;
237
;;----------------------------------------------------------------------------;;
238
;? decodes image data into RGB triplets and returns pointer to memory area of ;;
239
;? following structure:                                                       ;;
240
;? width  dd ?                                                                ;;
241
;? height dd ?                                                                ;;
242
;? rgb triplets                                                               ;;
243
;;----------------------------------------------------------------------------;;
244
;> [_img] = pointer to source image                                           ;;
245
;;----------------------------------------------------------------------------;;
246
;< eax = 0 / pointer to rgb_data (array of [rgb] triplets)                    ;;
247
;;============================================================================;;
248
        push    esi edi
249
        mov     esi, [_img]
250
        stdcall img._.validate, esi
251
        or      eax, eax
252
        jnz     .error
6807 dunkaist 253
 
8497 dunkaist 254
        mov     esi, [_img]
255
        mov     ecx, [esi + Image.Width]
256
        imul    ecx, [esi + Image.Height]
257
        lea     eax, [ecx * 3 + 4 * 3]
258
        invoke  mem.alloc, eax
259
        or      eax, eax
260
        jz      .error
6807 dunkaist 261
 
8497 dunkaist 262
        mov     edi, eax
263
        push    eax
264
        mov     eax, [esi + Image.Width]
265
        stosd
266
        mov     eax, [esi + Image.Height]
267
        stosd
268
        call    img._.do_rgb
269
        pop     eax
270
        pop     edi esi
271
        ret
6807 dunkaist 272
 
8497 dunkaist 273
.error:
274
        xor     eax, eax
275
        pop     edi esi
276
        ret
6807 dunkaist 277
endp
278
 
8497 dunkaist 279
;;============================================================================;;
280
proc img._.do_rgb ;///////////////////////////////////////////////////////////;;
281
;;----------------------------------------------------------------------------;;
282
;? decodes [esi + Image.Data] data into RGB triplets and stores them at [edi] ;;
283
;;----------------------------------------------------------------------------;;
284
;> esi = pointer to source image                                              ;;
285
;> edi = pointer to memory to store RGB triplets                              ;;
286
;;----------------------------------------------------------------------------;;
287
;< none                                                                       ;;
288
;;============================================================================;;
289
        mov     ecx, [esi + Image.Width]
290
        imul    ecx, [esi + Image.Height]
291
        mov     eax, [esi + Image.Type]
292
        jmp     dword [.handlers + (eax-1)*4]
6807 dunkaist 293
 
294
align 16
295
.bpp8i:
296
; 8 BPP WITH PALETTE -> 24 BPP
8497 dunkaist 297
        push    ebx
298
        mov     ebx, [esi + Image.Palette]
299
        mov     esi, [esi + Image.Data]
300
        sub     ecx, 1
301
        jz      .bpp8i.last
6807 dunkaist 302
@@:
8497 dunkaist 303
        movzx   eax, byte [esi]
304
        add     esi, 1
305
        mov     eax, [ebx + eax*4]
306
        mov     [edi], eax
307
        add     edi, 3
308
        sub     ecx, 1
309
        jnz     @b
6807 dunkaist 310
.bpp8i.last:
8497 dunkaist 311
        movzx   eax, byte [esi]
312
        mov     eax, [ebx + eax*4]
313
        mov     [edi], ax
314
        shr     eax, 16
315
        mov     [edi+2], al
316
        pop     ebx
317
        ret
6807 dunkaist 318
 
319
align 16
320
.bpp8g:
321
; 8 BPP GRAYSCALE -> 24 BPP
8497 dunkaist 322
        mov     esi, [esi + Image.Data]
6807 dunkaist 323
@@:
8497 dunkaist 324
        lodsb
325
        mov     ah, al
326
        stosb
327
        stosw
328
        dec     ecx
329
        jnz     @b
330
        ret
6807 dunkaist 331
;
332
;align 16
333
;.bpp8a: ; considered application layer, may be changed in the future
334
;; 8a BPP -> 24 BPP
335
;    mov esi, [esi + Image.Data]
336
;@@:
337
;    lodsw
338
;    mov ah, al
339
;    stosb
340
;    stosw
341
;    dec ecx
342
;    jnz @b
343
;    ret
344
 
345
; 15 BPP -> 24 BPP
346
.bpp15.intel:
8497 dunkaist 347
        push    ebx ebp
348
        sub     ecx, 4
349
        jb      .bpp15.tail
6807 dunkaist 350
align 16
351
.bpp15.intel.loop:
352
repeat 2
8497 dunkaist 353
        mov     ebx, [esi]
354
        mov     al, [esi]
355
        mov     ah, [esi+1]
356
        add     esi, 4
357
        and     al, 0x1F
358
        and     ah, 0x1F shl 2
359
        mov     ebp, ebx
360
        mov     dl, al
361
        mov     dh, ah
362
        shr     al, 2
363
        shr     ah, 4
364
        shl     dl, 3
365
        shl     dh, 1
366
        and     ebp, 0x1F shl 5
367
        add     al, dl
368
        add     ah, dh
369
        shr     ebp, 2
370
        mov     [edi], al
371
        mov     [edi+2], ah
372
        mov     eax, ebx
373
        mov     ebx, ebp
374
        shr     eax, 16
375
        shr     ebx, 5
376
        add     ebx, ebp
377
        mov     ebp, eax
378
        mov     [edi+1], bl
379
        and     eax, (0x1F) or (0x1F shl 10)
380
        and     ebp, 0x1F shl 5
381
        lea     edx, [eax+eax]
382
        shr     al, 2
383
        mov     ebx, ebp
384
        shr     ah, 4
385
        shl     dl, 2
386
        shr     ebx, 2
387
        shr     ebp, 7
388
        add     al, dl
389
        add     ah, dh
390
        mov     [edi+3], al
391
        add     ebx, ebp
392
        mov     [edi+5], ah
393
        mov     [edi+4], bl
394
        add     edi, 6
6807 dunkaist 395
end repeat
8497 dunkaist 396
        sub     ecx, 4
397
        jnb     .bpp15.intel.loop
6807 dunkaist 398
.bpp15.tail:
8497 dunkaist 399
        add     ecx, 4
400
        jz      .bpp15.done
6807 dunkaist 401
@@:
8497 dunkaist 402
        movzx   eax, word [esi]
403
        mov     ebx, eax
404
        add     esi, 2
405
        and     eax, (0x1F) or (0x1F shl 10)
406
        and     ebx, 0x1F shl 5
407
        lea     edx, [eax+eax]
408
        shr     al, 2
409
        mov     ebp, ebx
410
        shr     ebx, 2
411
        shr     ah, 4
412
        shl     dl, 2
413
        shr     ebp, 7
414
        add     eax, edx
415
        add     ebx, ebp
416
        mov     [edi], al
417
        mov     [edi+1], bl
418
        mov     [edi+2], ah
419
        add     edi, 3
420
        sub     ecx, 1
421
        jnz     @b
6807 dunkaist 422
.bpp15.done:
8497 dunkaist 423
        pop     ebp ebx
424
        ret
6807 dunkaist 425
 
426
.bpp15.amd:
8497 dunkaist 427
        push    ebx ebp
428
        sub     ecx, 4
429
        jb      .bpp15.tail
6807 dunkaist 430
align 16
431
.bpp15.amd.loop:
432
repeat 4
433
if (% mod 2) = 1
8497 dunkaist 434
        mov     eax, dword [esi]
435
        mov     ebx, dword [esi]
6807 dunkaist 436
else
8497 dunkaist 437
        movzx   eax, word [esi]
438
        mov     ebx, eax
6807 dunkaist 439
end if
8497 dunkaist 440
        add     esi, 2
441
        and     eax, (0x1F) or (0x1F shl 10)
442
        and     ebx, 0x1F shl 5
443
        lea     edx, [eax+eax]
444
        shr     al, 2
445
        mov     ebp, ebx
446
        shr     ebx, 2
447
        shr     ah, 4
448
        shl     dl, 2
449
        shr     ebp, 7
450
        add     eax, edx
451
        add     ebx, ebp
452
        mov     [edi], al
453
        mov     [edi+1], bl
454
        mov     [edi+2], ah
455
        add     edi, 3
6807 dunkaist 456
end repeat
8497 dunkaist 457
        sub     ecx, 4
458
        jnb     .bpp15.amd.loop
459
        jmp     .bpp15.tail
6807 dunkaist 460
 
461
; 16 BPP -> 24 BPP
462
.bpp16.intel:
8497 dunkaist 463
        push    ebx ebp
464
        sub     ecx, 4
465
        jb      .bpp16.tail
6807 dunkaist 466
align 16
467
.bpp16.intel.loop:
468
repeat 2
8497 dunkaist 469
        mov     ebx, [esi]
470
        mov     al, [esi]
471
        mov     ah, [esi+1]
472
        add     esi, 4
473
        and     al, 0x1F
474
        and     ah, 0x1F shl 3
475
        mov     ebp, ebx
476
        mov     dl, al
477
        mov     dh, ah
478
        shr     al, 2
479
        shr     ah, 5
480
        shl     dl, 3
481
        and     ebp, 0x3F shl 5
482
        add     al, dl
483
        add     ah, dh
484
        shr     ebp, 3
485
        mov     [edi], al
486
        mov     [edi+2], ah
487
        mov     eax, ebx
488
        mov     ebx, ebp
489
        shr     eax, 16
490
        shr     ebx, 6
491
        add     ebx, ebp
492
        mov     ebp, eax
493
        mov     [edi+1], bl
494
        and     eax, (0x1F) or (0x1F shl 11)
495
        and     ebp, 0x3F shl 5
496
        mov     edx, eax
497
        shr     al, 2
498
        mov     ebx, ebp
499
        shr     ah, 5
500
        shl     dl, 3
501
        shr     ebx, 3
502
        shr     ebp, 9
503
        add     al, dl
504
        add     ah, dh
505
        mov     [edi+3], al
506
        add     ebx, ebp
507
        mov     [edi+5], ah
508
        mov     [edi+4], bl
509
        add     edi, 6
6807 dunkaist 510
end repeat
8497 dunkaist 511
        sub     ecx, 4
512
        jnb     .bpp16.intel.loop
6807 dunkaist 513
.bpp16.tail:
8497 dunkaist 514
        add     ecx, 4
515
        jz      .bpp16.done
6807 dunkaist 516
@@:
8497 dunkaist 517
        movzx   eax, word [esi]
518
        mov     ebx, eax
519
        add     esi, 2
520
        and     eax, (0x1F) or (0x1F shl 11)
521
        and     ebx, 0x3F shl 5
522
        mov     edx, eax
523
        shr     al, 2
524
        mov     ebp, ebx
525
        shr     ebx, 3
526
        shr     ah, 5
527
        shl     dl, 3
528
        shr     ebp, 9
529
        add     eax, edx
530
        add     ebx, ebp
531
        mov     [edi], al
532
        mov     [edi+1], bl
533
        mov     [edi+2], ah
534
        add     edi, 3
535
        sub     ecx, 1
536
        jnz     @b
6807 dunkaist 537
.bpp16.done:
8497 dunkaist 538
        pop     ebp ebx
539
        ret
6807 dunkaist 540
 
541
.bpp16.amd:
8497 dunkaist 542
        push    ebx ebp
543
        sub     ecx, 4
544
        jb      .bpp16.tail
6807 dunkaist 545
align 16
546
.bpp16.amd.loop:
547
repeat 4
548
if (% mod 2) = 1
8497 dunkaist 549
        mov     eax, dword [esi]
550
        mov     ebx, dword [esi]
6807 dunkaist 551
else
8497 dunkaist 552
        movzx   eax, word [esi]
553
        mov     ebx, eax
6807 dunkaist 554
end if
8497 dunkaist 555
        add     esi, 2
556
        and     eax, (0x1F) or (0x1F shl 11)
557
        and     ebx, 0x3F shl 5
558
        mov     edx, eax
559
        shr     al, 2
560
        mov     ebp, ebx
561
        shr     ebx, 3
562
        shr     ah, 5
563
        shl     dl, 3
564
        shr     ebp, 9
565
        add     eax, edx
566
        add     ebx, ebp
567
        mov     [edi], al
568
        mov     [edi+1], bl
569
        mov     [edi+2], ah
570
        add     edi, 3
6807 dunkaist 571
end repeat
8497 dunkaist 572
        sub     ecx, 4
573
        jnb     .bpp16.amd.loop
574
        jmp     .bpp16.tail
6807 dunkaist 575
 
576
align 16
577
.bpp24:
578
; 24 BPP -> 24 BPP
8497 dunkaist 579
        lea     ecx, [ecx*3 + 3]
580
        mov     esi, [esi + Image.Data]
581
        shr     ecx, 2
582
        rep movsd
583
        ret
6807 dunkaist 584
 
585
align 16
586
.bpp32:
587
; 32 BPP -> 24 BPP
8497 dunkaist 588
        mov     esi, [esi + Image.Data]
6807 dunkaist 589
 
8497 dunkaist 590
@@:
591
        mov     eax, [esi]
592
        mov     [edi], ax
593
        shr     eax, 16
594
        mov     [edi+2], al
595
        add     esi, 4
596
        add     edi, 3
597
        sub     ecx, 1
598
        jnz     @b
6807 dunkaist 599
 
8497 dunkaist 600
@@:
601
        ret
6807 dunkaist 602
 
603
align 16
604
.bpp1:
8497 dunkaist 605
        push    ebx ebp
606
        mov     ebp, [esi + Image.Width]
607
        mov     edx, [esi + Image.Height]
608
        shl     edx, 16
609
        mov     ebx, [esi + Image.Palette]
610
        mov     esi, [esi + Image.Data]
611
.bpp1.pre:
612
        mov     dx, bp
613
        mov     ecx, 7
614
.bpp1.begin:
615
        xor     eax, eax
616
        bt      [esi], ecx
617
        adc     eax, 0
618
        mov     eax, [ebx + eax*4]
619
        mov     [edi], ax
620
        shr     eax, 16
621
        mov     [edi + 2], al
622
        add     edi, 3
623
        dec     dx
624
        jz      .bpp1.end_line
625
        dec     ecx
626
        jns     .bpp1.begin
627
        mov     ecx, 7
628
        inc     esi
629
        jmp     .bpp1.begin
630
.bpp1.end_line:
631
        sub     edx, 0x10000
632
        jz      .bpp1.quit
633
        inc     esi
634
        jmp     .bpp1.pre
635
.bpp1.quit:
636
        pop     ebp ebx
637
        ret
6807 dunkaist 638
 
639
align 16
640
.bpp2i:
8497 dunkaist 641
        push    ebx ebp
642
        mov     ebp, [esi + Image.Width]
643
        mov     edx, [esi + Image.Height]
644
        shl     edx, 16
645
        mov     ebx, [esi + Image.Palette]
646
        mov     esi, [esi + Image.Data]
647
.bpp2i.pre:
648
        mov     dx, bp
649
        mov     ecx, 3
650
.bpp2i.begin:
651
        mov     eax, 3
652
        shl     ecx, 1
653
        shl     eax, cl
654
        and     al, [esi]
655
        shr     eax, cl
656
        shr     ecx, 1
657
        mov     eax, [ebx + eax*4]
658
        mov     [edi], ax
659
        shr     eax, 16
660
        mov     [edi + 2], al
661
        add     edi, 3
662
        dec     dx
663
        jz      .bpp2i.end_line
664
        dec     ecx
665
        jns     .bpp2i.begin
666
        mov     ecx, 3
667
        inc     esi
668
        jmp     .bpp2i.begin
669
.bpp2i.end_line:
670
        sub     edx, 0x10000
671
        jz      .bpp2i.quit
672
        inc     esi
673
        jmp     .bpp2i.pre
674
.bpp2i.quit:
675
        pop     ebp ebx
676
        ret
6807 dunkaist 677
 
678
align 16
679
.bpp4i:
8497 dunkaist 680
        push    ebx ebp
681
        mov     ebp, [esi + Image.Width]
682
        mov     edx, [esi + Image.Height]
683
        shl     edx, 16
684
        mov     ebx, [esi + Image.Palette]
685
        mov     esi, [esi + Image.Data]
686
.bpp4i.pre:
687
        mov     dx, bp
688
        mov     ecx, 1
689
.bpp4i.begin:
690
        mov     eax, 15
691
        shl     ecx, 2
692
        shl     eax, cl
693
        and     al, [esi]
694
        shr     eax, cl
695
        shr     ecx, 2
696
        mov     eax, [ebx + eax*4]
697
        mov     [edi], ax
698
        shr     eax, 16
699
        mov     [edi + 2], al
700
        add     edi, 3
701
        dec     dx
702
        jz      .bpp4i.end_line
703
        dec     ecx
704
        jns     .bpp4i.begin
705
        mov     ecx, 1
706
        inc     esi
707
        jmp     .bpp4i.begin
708
.bpp4i.end_line:
709
        sub     edx, 0x10000
710
        jz      .bpp4i.quit
711
        inc     esi
712
        jmp     .bpp4i.pre
713
.bpp4i.quit:
714
        pop     ebp ebx
715
        ret
6807 dunkaist 716
 
717
endp
718
 
8497 dunkaist 719
;;============================================================================;;
720
proc img.decode _data, _length, _options ;////////////////////////////////////;;
721
;;----------------------------------------------------------------------------;;
722
;? decodes loaded into memory graphic file                                    ;;
723
;;----------------------------------------------------------------------------;;
724
;> [_data]    = pointer to file in memory                                     ;;
725
;> [_length]  = size in bytes of memory area pointed to by [_data]            ;;
726
;> [_options] = 0 / pointer to the structure of additional options            ;;
727
;;----------------------------------------------------------------------------;;
728
;< eax = 0 / pointer to image                                                 ;;
729
;;============================================================================;;
730
        push    ebx
731
        mov     ebx, [_length]
732
        or      ebx, ebx
733
        jz      .fail
734
        mov     ebx, img.formats_table
735
@@:
736
        stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
737
        or      eax, eax
738
        jnz     @f
739
        add     ebx, sizeof.FormatsTableEntry
740
        cmp     dword[ebx], eax ;0
741
        jnz     @b
742
.fail:
743
        xor     eax, eax
744
        pop     ebx
745
        ret
746
@@:
747
        mov     eax, [ebx + FormatsTableEntry.Decode]
748
        pop     ebx
749
        leave
750
        jmp     eax
6807 dunkaist 751
endp
752
 
8497 dunkaist 753
;;============================================================================;;
754
proc img.encode uses ebx, _img, _common, _specific ;//////////////////////////;;
755
;;----------------------------------------------------------------------------;;
756
;? encode image to some format                                                ;;
757
;;----------------------------------------------------------------------------;;
758
;> [_img]      = pointer to input image                                       ;;
759
;> [_common]   = some most important/common options                           ;;
760
;     0x00 :  byte : format id (defined in libimg.inc)                        ;;
761
;     0x01 :  byte : fast encoding (0) / best compression ratio (255)         ;;
762
;                    0 : store uncompressed data (if supported both by the    ;;
763
;                        format and libimg)                                   ;;
764
;                    1 - 255 : use compression, if supported                  ;;
765
;                        this option may be ignored if any format specific    ;;
766
;                        options are defined, i.e. 0 here will be ignored if  ;;
767
;                        particular compression algorithm is specified        ;;
768
;     0x02 :  byte : flags (bitfield)                                         ;;
769
;                    0x01 : return an error if format specific conditions     ;;
770
;                           cannot be met                                     ;;
771
;                    0x02 : preserve current bit depth. means 8bpp/16bpp/     ;;
772
;                           24bpp and so on                                   ;;
773
;                    0x04 : delete alpha channel, if any                      ;;
774
;                    0x08 : flush alpha channel with 0xff, if any; add it if  ;;
775
;                           none                                              ;;
776
;     0x03 :  byte : reserved, must be 0                                      ;;
777
;> [_specific] = 0 / pointer to the structure of format specific options      ;;
778
;                   see .inc for description                     ;;
779
;;----------------------------------------------------------------------------;;
780
;< eax = 0 / pointer to encoded data                                          ;;
781
;< ecx = error code / the size of encoded data                                ;;
782
;     1 : out of memory                                                       ;;
783
;     2 : format is not supported                                             ;;
784
;     3 : specific conditions cannot be satisfied                             ;;
785
;     4 : bit depth cannot be preserved                                       ;;
786
;;============================================================================;;
787
        mov     ebx, [_img]
6807 dunkaist 788
 
8497 dunkaist 789
        movzx   eax, byte[_common]
790
        dec     eax
791
        imul    eax, sizeof.FormatsTableEntry
792
        add     eax, FormatsTableEntry.Capabilities
793
        add     eax, img.formats_table
794
        mov     eax, [eax]
795
        test    eax, 1          ; is encoding to this format supported at all?
796
        jnz     @f
797
        mov     ecx, LIBIMG_ERROR_FORMAT
798
        jmp     .error
799
@@:
800
        mov     ecx, [ebx + Image.Type]
801
        mov     edx, 1
802
        shl     edx, cl
803
        test    eax, edx
804
        jnz     .bit_depth_ok
805
        test    byte[_common+2], LIBIMG_ENCODE_STRICT_BIT_DEPTH
806
        jz      @f
807
        mov     ecx, LIBIMG_ERROR_BIT_DEPTH
808
        jmp     .error
809
@@:
810
        mov     edx, 1 SHL Image.bpp24
811
        test    eax, edx
812
        jnz     @f
813
        mov     ecx, LIBIMG_ERROR_BIT_DEPTH
814
        jmp     .error
815
@@:
816
        stdcall img.create, [ebx + Image.Width], [ebx + Image.Height], Image.bpp24
817
        test    eax, eax
818
        jnz     @f
819
        mov     ecx, LIBIMG_ERROR_OUT_OF_MEMORY
820
        jmp     .error
821
@@:
822
        push    eax
823
        stdcall img.to_rgb2, ebx, [eax + Image.Data]
824
        pop     ebx
6807 dunkaist 825
 
8497 dunkaist 826
.bit_depth_ok:
827
        movzx   eax, byte[_common]
828
        dec     eax
829
        imul    eax, sizeof.FormatsTableEntry
830
        add     eax, FormatsTableEntry.Encode
831
        add     eax, img.formats_table
832
        mov     eax, [eax]
833
        stdcall eax, [_img], [_common], [_specific]
834
        push    eax ecx
835
        cmp     ebx, [_img]
836
        je      @f
837
        stdcall img.destroy, ebx
838
@@:
839
        pop     ecx eax
840
        jmp     .quit
6807 dunkaist 841
 
8497 dunkaist 842
.error:
843
        xor     eax, eax
844
.quit:
845
        ret
6807 dunkaist 846
endp
847
 
8497 dunkaist 848
;;============================================================================;;
849
proc img.create _width, _height, _type ;//////////////////////////////////////;;
850
;;----------------------------------------------------------------------------;;
851
;? creates an Image structure and initializes some its fields                 ;;
852
;;----------------------------------------------------------------------------;;
853
;> [_width]  = width of an image in pixels                                    ;;
854
;> [_height] = height of an image in pixels                                   ;;
855
;> [_type]   = one of the Image.bppN constants from libimg.inc                ;;
856
;;----------------------------------------------------------------------------;;
857
;< eax = 0 / pointer to image                                                 ;;
858
;;============================================================================;;
859
        push    ecx
6807 dunkaist 860
 
8497 dunkaist 861
        stdcall img._.new
862
        or      eax, eax
863
        jz      .error
6807 dunkaist 864
 
8497 dunkaist 865
        mov     ecx, [_type]
866
        mov     [eax + Image.Type], ecx
6807 dunkaist 867
 
8497 dunkaist 868
        push    eax
6807 dunkaist 869
 
8497 dunkaist 870
        stdcall img.resize_data, eax, [_width], [_height]
871
        or      eax, eax
872
        jz      .error.2
6807 dunkaist 873
 
8497 dunkaist 874
        pop     eax
875
        jmp     .ret
6807 dunkaist 876
 
8497 dunkaist 877
.error.2:
878
;       pop     eax
879
        stdcall img._.delete; eax
880
        xor     eax, eax
6807 dunkaist 881
 
8497 dunkaist 882
.error:
883
.ret:
884
        pop     ecx
885
        ret
6807 dunkaist 886
endp
887
 
8497 dunkaist 888
;;============================================================================;;
889
proc img.destroy.layer _img ;/////////////////////////////////////////////////;;
890
;;----------------------------------------------------------------------------;;
891
;? Frees memory occupied by an image and all the memory regions its fields    ;;
892
;? point to. For image sequences deletes only one frame and fixes Previous/   ;;
893
;? Next pointers.                                                             ;;
894
;;----------------------------------------------------------------------------;;
895
;> [_img] = pointer to image                                                  ;;
896
;;----------------------------------------------------------------------------;;
897
;< eax = 0 (fail) / 1 (success)                                               ;;
898
;;============================================================================;;
899
        mov     eax, [_img]
900
        mov     edx, [eax + Image.Previous]
901
        test    edx, edx
902
        jz      @f
903
        push    [eax + Image.Next]
904
        pop     [edx + Image.Next]
6807 dunkaist 905
@@:
8497 dunkaist 906
        mov     edx, [eax + Image.Next]
907
        test    edx, edx
908
        jz      @f
909
        push    [eax + Image.Previous]
910
        pop     [edx + Image.Previous]
6807 dunkaist 911
@@:
8497 dunkaist 912
        stdcall img._.delete, eax
913
        ret
6807 dunkaist 914
endp
915
 
8497 dunkaist 916
;;============================================================================;;
917
proc img.destroy _img ;///////////////////////////////////////////////////////;;
918
;;----------------------------------------------------------------------------;;
919
;? Frees memory occupied by an image and all the memory regions its fields    ;;
920
;? point to. Follows Previous/Next pointers and deletes all the images in     ;;
921
;? sequence.                                                                  ;;
922
;;----------------------------------------------------------------------------;;
923
;> [_img] = pointer to image                                                  ;;
924
;;----------------------------------------------------------------------------;;
925
;< eax = 0 (fail) / 1 (success)                                               ;;
926
;;============================================================================;;
927
        push    1
928
        mov     eax, [_img]
929
        mov     eax, [eax + Image.Previous]
6807 dunkaist 930
.destroy_prev_loop:
8497 dunkaist 931
        test    eax, eax
932
        jz      .destroy_prev_done
933
        pushd   [eax + Image.Previous]
934
        stdcall img._.delete, eax
935
        test    eax, eax
936
        jnz     @f
937
        mov     byte [esp+4], 0
6807 dunkaist 938
@@:
8497 dunkaist 939
        pop     eax
940
        jmp     .destroy_prev_loop
6807 dunkaist 941
.destroy_prev_done:
8497 dunkaist 942
        mov     eax, [_img]
6807 dunkaist 943
.destroy_next_loop:
8497 dunkaist 944
        pushd   [eax + Image.Next]
945
        stdcall img._.delete, eax
946
        test    eax, eax
947
        jnz     @f
948
        mov     byte [esp+4], 0
6807 dunkaist 949
@@:
8497 dunkaist 950
        pop     eax
951
        test    eax, eax
952
        jnz     .destroy_next_loop
953
        pop     eax
954
        ret
6807 dunkaist 955
endp
956
 
8497 dunkaist 957
;;============================================================================;;
958
proc img.count _img ;/////////////////////////////////////////////////////////;;
959
;;----------------------------------------------------------------------------;;
960
;? Get number of images in the list (e.g. in animated GIF file)               ;;
961
;;----------------------------------------------------------------------------;;
962
;> _img = pointer to image                                                    ;;
963
;;----------------------------------------------------------------------------;;
964
;< eax = -1 (fail) / >0 (ok)                                                  ;;
965
;;============================================================================;;
966
        push    ecx edx
967
        mov     edx, [_img]
968
        stdcall img._.validate, edx
969
        or      eax, eax
970
        jnz     .error
6807 dunkaist 971
 
8497 dunkaist 972
@@:
973
        mov     eax, [edx + Image.Previous]
974
        or      eax, eax
975
        jz      @f
976
        mov     edx, eax
977
        jmp     @b
6807 dunkaist 978
 
8497 dunkaist 979
@@:
980
        xor     ecx, ecx
981
@@:
982
        inc     ecx
983
        mov     eax, [edx + Image.Next]
984
        or      eax, eax
985
        jz      .exit
986
        mov     edx, eax
987
        jmp     @b
6807 dunkaist 988
 
8497 dunkaist 989
.exit:
990
        mov     eax, ecx
991
        pop     edx ecx
992
        ret
6807 dunkaist 993
 
8497 dunkaist 994
.error:
995
        or      eax, -1
996
        pop     edx ecx
997
        ret
6807 dunkaist 998
endp
999
 
8497 dunkaist 1000
;;//// image processing //////////////////////////////////////////////////////;;
6807 dunkaist 1001
 
8497 dunkaist 1002
;;============================================================================;;
1003
proc img.lock_bits _img, _start_line, _end_line ;/////////////////////////////;;
1004
;;----------------------------------------------------------------------------;;
1005
;? --- TBD ---                                                                ;;
1006
;;----------------------------------------------------------------------------;;
1007
;> --- TBD ---                                                                ;;
1008
;;----------------------------------------------------------------------------;;
1009
;< eax = 0 / pointer to bits                                                  ;;
1010
;;============================================================================;;
1011
        xor     eax, eax
1012
        ret
6807 dunkaist 1013
endp
1014
 
8497 dunkaist 1015
;;============================================================================;;
1016
proc img.unlock_bits _img, _lock ;////////////////////////////////////////////;;
1017
;;----------------------------------------------------------------------------;;
1018
;? --- TBD ---                                                                ;;
1019
;;----------------------------------------------------------------------------;;
1020
;> --- TBD ---                                                                ;;
1021
;;----------------------------------------------------------------------------;;
1022
;< eax = false / true                                                         ;;
1023
;;============================================================================;;
1024
        xor     eax, eax
1025
        ret
6807 dunkaist 1026
endp
1027
 
8497 dunkaist 1028
;;============================================================================;;
1029
proc img.flip.layer _img, _flip_kind ;////////////////////////////////////////;;
1030
;;----------------------------------------------------------------------------;;
1031
;? Flip image layer                                                           ;;
1032
;;----------------------------------------------------------------------------;;
1033
;> _img = pointer to image                                                    ;;
1034
;> _flip_kind = one of FLIP_* constants                                       ;;
1035
;;----------------------------------------------------------------------------;;
1036
;< eax = false / true                                                         ;;
1037
;;============================================================================;;
6807 dunkaist 1038
locals
1039
  scanline_len dd ?
1040
endl
1041
 
8497 dunkaist 1042
        push    ebx esi edi
1043
        mov     ebx, [_img]
1044
        stdcall img._.validate, ebx
1045
        or      eax, eax
1046
        jnz     .error
6807 dunkaist 1047
 
8497 dunkaist 1048
        mov     ecx, [ebx + Image.Height]
1049
        mov     eax, [ebx + Image.Width]
1050
        call    img._.get_scanline_len
1051
        mov     [scanline_len], eax
6807 dunkaist 1052
 
8497 dunkaist 1053
        test    [_flip_kind], FLIP_VERTICAL
1054
        jz      .dont_flip_vert
6807 dunkaist 1055
 
8497 dunkaist 1056
        imul    eax, ecx
1057
        sub     eax, [scanline_len]
1058
        shr     ecx, 1
1059
        mov     esi, [ebx + Image.Data]
1060
        lea     edi, [esi + eax]
6807 dunkaist 1061
 
8497 dunkaist 1062
.next_line_vert:
1063
        push    ecx
6807 dunkaist 1064
 
8497 dunkaist 1065
        mov     ecx, [scanline_len]
1066
        push    ecx
1067
        shr     ecx, 2
1068
@@:
1069
        dec     ecx
1070
        js      @f
1071
        mov     eax, [esi]
1072
        xchg    eax, [edi]
1073
        mov     [esi], eax
1074
        add     esi, 4
1075
        add     edi, 4
1076
        jmp     @b
1077
@@:
6807 dunkaist 1078
 
8497 dunkaist 1079
        pop     ecx
1080
        and     ecx, 3
1081
        jz      .cont_line_vert
1082
@@:
1083
        mov     al, [esi]
1084
        xchg    al, [edi]
1085
        mov     [esi], al
1086
        add     esi, 1
1087
        add     edi, 1
1088
        dec     ecx
1089
        jnz     @b
1090
.cont_line_vert:
6807 dunkaist 1091
 
8497 dunkaist 1092
        pop     ecx
1093
        mov     eax, [scanline_len]
1094
        shl     eax, 1
1095
        sub     edi, eax
1096
        dec     ecx
1097
        jnz     .next_line_vert
6807 dunkaist 1098
 
8497 dunkaist 1099
.dont_flip_vert:
6807 dunkaist 1100
 
8497 dunkaist 1101
        test    [_flip_kind], FLIP_HORIZONTAL
1102
        jz      .exit
6807 dunkaist 1103
 
8497 dunkaist 1104
        mov     ecx, [ebx + Image.Height]
1105
        mov     eax, [ebx + Image.Type]
1106
        mov     esi, [ebx + Image.Data]
1107
        mov     edi, [scanline_len]
1108
        add     edi, esi
1109
        jmp     dword [.handlers_horz + (eax-1)*4]
6807 dunkaist 1110
 
1111
.bpp32_horz:
8497 dunkaist 1112
        sub     edi, 4
6807 dunkaist 1113
 
8497 dunkaist 1114
.next_line_horz:
1115
        push    ecx esi edi
6807 dunkaist 1116
 
8497 dunkaist 1117
        mov     ecx, [scanline_len]
1118
        shr     ecx, 3
1119
@@:
1120
        mov     eax, [esi]
1121
        xchg    eax, [edi]
1122
        mov     [esi], eax
1123
        add     esi, 4
1124
        add     edi, -4
1125
        sub     ecx, 1
1126
        jnz     @b
6807 dunkaist 1127
 
8497 dunkaist 1128
        pop     edi esi ecx
1129
        add     esi, [scanline_len]
1130
        add     edi, [scanline_len]
1131
        dec     ecx
1132
        jnz     .next_line_horz
1133
        jmp     .exit
6807 dunkaist 1134
 
1135
.bpp1x_horz:
8497 dunkaist 1136
        sub     edi, 2
1137
.next_line_horz1x:
1138
        push    ecx esi edi
6807 dunkaist 1139
 
8497 dunkaist 1140
        mov     ecx, [ebx + Image.Width]
1141
@@:
1142
        mov     ax, [esi]
1143
        mov     dx, [edi]
1144
        mov     [edi], ax
1145
        mov     [esi], dx
1146
        add     esi, 2
1147
        sub     edi, 2
1148
        sub     ecx, 2
1149
        ja      @b
6807 dunkaist 1150
 
8497 dunkaist 1151
        pop     edi esi ecx
1152
        add     esi, [scanline_len]
1153
        add     edi, [scanline_len]
1154
        dec     ecx
1155
        jnz     .next_line_horz1x
1156
        jmp     .exit
6807 dunkaist 1157
 
1158
.bpp8ig_horz:
8497 dunkaist 1159
        dec     edi
1160
.next_line_horz8ig:
1161
        push    ecx esi edi
6807 dunkaist 1162
 
8497 dunkaist 1163
        mov     ecx, [scanline_len]
1164
        shr     ecx, 1
1165
@@:
1166
        mov     al, [esi]
1167
        mov     dl, [edi]
1168
        mov     [edi], al
1169
        mov     [esi], dl
1170
        add     esi, 1
1171
        sub     edi, 1
1172
        sub     ecx, 1
1173
        jnz     @b
6807 dunkaist 1174
 
8497 dunkaist 1175
        pop     edi esi ecx
1176
        add     esi, [scanline_len]
1177
        add     edi, [scanline_len]
1178
        dec     ecx
1179
        jnz     .next_line_horz8ig
1180
        jmp     .exit
6807 dunkaist 1181
 
1182
.bpp24_horz:
8497 dunkaist 1183
        sub     edi, 3
1184
.next_line_horz24:
1185
        push    ecx esi edi
6807 dunkaist 1186
 
8497 dunkaist 1187
        mov     ecx, [ebx + Image.Width]
1188
@@:
1189
        mov     al, [esi]
1190
        mov     dl, [edi]
1191
        mov     [edi], al
1192
        mov     [esi], dl
1193
        mov     al, [esi+1]
1194
        mov     dl, [edi+1]
1195
        mov     [edi+1], al
1196
        mov     [esi+1], dl
1197
        mov     al, [esi+2]
1198
        mov     dl, [edi+2]
1199
        mov     [edi+2], al
1200
        mov     [esi+2], dl
1201
        add     esi, 3
1202
        sub     edi, 3
1203
        sub     ecx, 2
1204
        ja      @b
6807 dunkaist 1205
 
8497 dunkaist 1206
        pop     edi esi ecx
1207
        add     esi, [scanline_len]
1208
        add     edi, [scanline_len]
1209
        dec     ecx
1210
        jnz     .next_line_horz24
1211
        jmp     .exit
6807 dunkaist 1212
 
1213
.bpp1_horz:
8497 dunkaist 1214
        mov     edi, [scanline_len]
1215
        mov     edx, [ebx + Image.Width]
1216
        and     edx, 7
1217
        neg     edx
1218
        add     edx, 8
1219
        and     edx, 7
6807 dunkaist 1220
.bpp1_horz.begin:
8497 dunkaist 1221
        push    ebx edx esi
1222
        mov     eax, 7
1223
        add     edi, esi
1224
        sub     edi, 1
1225
        mov     ebx, [ebx + Image.Width]
1226
        shr     ebx, 1
6807 dunkaist 1227
.bpp1_horz.bit:
8497 dunkaist 1228
        bt      [edi], edx
1229
        jc      @f
1230
        btr     [esi], eax
1231
        jmp     .bpp1_horz.right
1232
@@:
1233
        bts     [esi], eax
1234
.bpp1_horz.right:
1235
        jnc     @f
1236
        bts     [edi], edx
1237
        jmp     .bpp1_horz.bit_done
1238
@@:
1239
        btr     [edi], edx
1240
.bpp1_horz.bit_done:
1241
        inc     edx
1242
        and     edx, 7
1243
        jnz     @f
1244
        dec     edi
1245
@@:
1246
        dec     eax
1247
        jns     @f
1248
        mov     eax, 7
1249
        inc     esi
1250
@@:
1251
        dec     ebx
1252
        jnz     .bpp1_horz.bit
6807 dunkaist 1253
 
8497 dunkaist 1254
        pop     esi edx ebx
1255
        add     esi, [scanline_len]
1256
        mov     edi, [scanline_len]
1257
        dec     ecx
1258
        jnz     .bpp1_horz.begin
1259
        jmp     .exit
6807 dunkaist 1260
 
1261
 
1262
.bpp2i_horz:
8497 dunkaist 1263
        mov     edi, [scanline_len]
1264
        mov     edx, [ebx + Image.Width]
1265
        and     edx, 3
1266
        neg     edx
1267
        add     edx, 4
1268
        and     edx, 3
6807 dunkaist 1269
.bpp2i_horz.begin:
8497 dunkaist 1270
        push    ebx edx esi
1271
        mov     eax, 3
1272
        add     edi, esi
1273
        sub     edi, 1
1274
        mov     ebx, [ebx + Image.Width]
1275
        shr     ebx, 1
6807 dunkaist 1276
.bpp2i_horz.pixel:
8497 dunkaist 1277
        push    ebx ecx
1278
        mov     ebx, 3
1279
        mov     ecx, edx
1280
        shl     ebx, cl
1281
        shl     ebx, cl
1282
        and     bl, [edi]
1283
        shr     ebx, cl
1284
        shr     ebx, cl
1285
        mov     bh, 3
1286
        mov     ecx, eax
1287
        shl     ebx, cl
1288
        shl     ebx, cl
1289
        not     bh
1290
        and     bh, [esi]
1291
        or      bl, bh
1292
        mov     bh, [esi]
1293
        mov     [esi], bl
1294
        shr     ebx, 8
1295
        shr     ebx, cl
1296
        shr     ebx, cl
1297
        and     ebx, 3
1298
        mov     bh, 3
1299
        mov     ecx, edx
1300
        shl     ebx, cl
1301
        shl     ebx, cl
1302
        not     bh
1303
        and     bh, [edi]
1304
        or      bl, bh
1305
        mov     [edi], bl
1306
        pop     ecx ebx
1307
.bpp2i_horz.pixel_done:
1308
        inc     edx
1309
        and     edx, 3
1310
        jnz     @f
1311
        dec     edi
1312
@@:
1313
        dec     eax
1314
        jns     @f
1315
        mov     eax, 3
1316
        inc     esi
1317
@@:
1318
        dec     ebx
1319
        jnz     .bpp2i_horz.pixel
6807 dunkaist 1320
 
8497 dunkaist 1321
        pop     esi edx ebx
1322
        add     esi, [scanline_len]
1323
        mov     edi, [scanline_len]
1324
        dec     ecx
1325
        jnz     .bpp2i_horz.begin
1326
        jmp     .exit
6807 dunkaist 1327
 
1328
 
1329
.bpp4i_horz:
8497 dunkaist 1330
        mov     edi, [scanline_len]
1331
        mov     edx, [ebx + Image.Width]
1332
        and     edx, 1
1333
        neg     edx
1334
        add     edx, 2
1335
        and     edx, 1
6807 dunkaist 1336
.bpp4i_horz.begin:
8497 dunkaist 1337
        push    ebx edx esi
1338
        mov     eax, 1
1339
        add     edi, esi
1340
        sub     edi, 1
1341
        mov     ebx, [ebx + Image.Width]
1342
        shr     ebx, 1
6807 dunkaist 1343
.bpp4i_horz.pixel:
8497 dunkaist 1344
        push    ebx ecx
1345
        mov     ebx, 15
1346
        mov     ecx, edx
1347
        shl     ecx, 2
1348
        shl     ebx, cl
1349
        and     bl, [edi]
1350
        shr     ebx, cl
1351
        mov     bh, 15
1352
        mov     ecx, eax
1353
        shl     ecx, 2
1354
        shl     ebx, cl
1355
        not     bh
1356
        and     bh, [esi]
1357
        or      bl, bh
1358
        mov     bh, [esi]
1359
        mov     [esi], bl
1360
        shr     ebx, 8
1361
        shr     ebx, cl
1362
        and     ebx, 15
1363
        mov     bh, 15
1364
        mov     ecx, edx
1365
        shl     ecx, 2
1366
        shl     ebx, cl
1367
        not     bh
1368
        and     bh, [edi]
1369
        or      bl, bh
1370
        mov     [edi], bl
1371
        pop     ecx ebx
1372
.bpp4i_horz.pixel_done:
1373
        inc     edx
1374
        and     edx, 1
1375
        jnz     @f
1376
        dec     edi
1377
@@:
1378
        dec     eax
1379
        jns     @f
1380
        mov     eax, 1
1381
        inc     esi
1382
@@:
1383
        dec     ebx
1384
        jnz     .bpp4i_horz.pixel
6807 dunkaist 1385
 
8497 dunkaist 1386
        pop     esi edx ebx
1387
        add     esi, [scanline_len]
1388
        mov     edi, [scanline_len]
1389
        dec     ecx
1390
        jnz     .bpp4i_horz.begin
1391
        jmp     .exit
6807 dunkaist 1392
 
1393
 
8497 dunkaist 1394
.exit:
1395
        xor     eax, eax
1396
        inc     eax
1397
        pop     edi esi ebx
1398
        ret
6807 dunkaist 1399
 
8497 dunkaist 1400
.error:
1401
        xor     eax, eax
1402
        pop     edi esi ebx
1403
        ret
6807 dunkaist 1404
endp
1405
 
8497 dunkaist 1406
;;============================================================================;;
1407
proc img.flip _img, _flip_kind ;//////////////////////////////////////////////;;
1408
;;----------------------------------------------------------------------------;;
1409
;? Flip all layers of image                                                   ;;
1410
;;----------------------------------------------------------------------------;;
1411
;> _img = pointer to image                                                    ;;
1412
;> _flip_kind = one of FLIP_* constants                                       ;;
1413
;;----------------------------------------------------------------------------;;
1414
;< eax = false / true                                                         ;;
1415
;;============================================================================;;
1416
        push    1
1417
        mov     ebx, [_img]
6807 dunkaist 1418
@@:
8497 dunkaist 1419
        mov     eax, [ebx + Image.Previous]
1420
        test    eax, eax
1421
        jz      .loop
1422
        mov     ebx, eax
1423
        jmp     @b
6807 dunkaist 1424
.loop:
8497 dunkaist 1425
        stdcall img.flip.layer, ebx, [_flip_kind]
1426
        test    eax, eax
1427
        jnz     @f
1428
        mov     byte [esp], 0
6807 dunkaist 1429
@@:
8497 dunkaist 1430
        mov     ebx, [ebx + Image.Next]
1431
        test    ebx, ebx
1432
        jnz     .loop
1433
        pop     eax
1434
        ret
6807 dunkaist 1435
endp
1436
 
8497 dunkaist 1437
;;============================================================================;;
1438
proc img.rotate.layer _img, _rotate_kind ;////////////////////////////////////;;
1439
;;----------------------------------------------------------------------------;;
1440
;? Rotate image layer                                                         ;;
1441
;;----------------------------------------------------------------------------;;
1442
;> _img = pointer to image                                                    ;;
1443
;> _rotate_kind = one of ROTATE_* constants                                   ;;
1444
;;----------------------------------------------------------------------------;;
1445
;< eax = false / true                                                         ;;
1446
;;============================================================================;;
6807 dunkaist 1447
locals
1448
  scanline_len_old    dd ?
1449
  scanline_len_new    dd ?
1450
  scanline_pixels_new dd ?
8497 dunkaist 1451
  line_buffer         dd ?
1452
  pixels_ptr          dd ?
6807 dunkaist 1453
endl
1454
 
8497 dunkaist 1455
        mov     [line_buffer], 0
6807 dunkaist 1456
 
8497 dunkaist 1457
        push    ebx esi edi
1458
        mov     ebx, [_img]
1459
        stdcall img._.validate, ebx
1460
        or      eax, eax
1461
        jnz     .error
6807 dunkaist 1462
 
8497 dunkaist 1463
        cmp     [_rotate_kind], ROTATE_90_CCW
1464
        je      .rotate_ccw_low
1465
        cmp     [_rotate_kind], ROTATE_90_CW
1466
        je      .rotate_cw_low
1467
        cmp     [_rotate_kind], ROTATE_180
1468
        je      .flip
1469
        jmp     .exit
6807 dunkaist 1470
 
8497 dunkaist 1471
.rotate_ccw_low:
1472
        mov     eax, [ebx + Image.Height]
1473
        mov     [scanline_pixels_new], eax
1474
        call    img._.get_scanline_len
1475
        mov     [scanline_len_new], eax
6807 dunkaist 1476
 
8497 dunkaist 1477
        invoke  mem.alloc, eax
1478
        or      eax, eax
1479
        jz      .error
1480
        mov     [line_buffer], eax
6807 dunkaist 1481
 
8497 dunkaist 1482
        mov     eax, [ebx + Image.Width]
1483
        mov     ecx, eax
1484
        call    img._.get_scanline_len
1485
        mov     [scanline_len_old], eax
6807 dunkaist 1486
 
8497 dunkaist 1487
        mov     eax, [scanline_len_new]
1488
        imul    eax, ecx
1489
        add     eax, [ebx + Image.Data]
1490
        mov     [pixels_ptr], eax
6807 dunkaist 1491
 
8497 dunkaist 1492
        cmp     [ebx + Image.Type], Image.bpp1
1493
        jz      .rotate_ccw1
1494
        cmp     [ebx + Image.Type], Image.bpp2i
1495
        jz      .rotate_ccw2i
1496
        cmp     [ebx + Image.Type], Image.bpp4i
1497
        jz      .rotate_ccw4i
1498
        cmp     [ebx + Image.Type], Image.bpp8i
1499
        jz      .rotate_ccw8ig
1500
        cmp     [ebx + Image.Type], Image.bpp8g
1501
        jz      .rotate_ccw8ig
1502
        cmp     [ebx + Image.Type], Image.bpp24
1503
        jz      .rotate_ccw24
1504
        cmp     [ebx + Image.Type], Image.bpp32
1505
        jz      .rotate_ccw32
6807 dunkaist 1506
 
8497 dunkaist 1507
.next_column_ccw_low1x:
1508
        dec     ecx
1509
        js      .exchange_dims
1510
        push    ecx
6807 dunkaist 1511
 
8497 dunkaist 1512
        mov     edx, [scanline_len_old]
1513
        add     [scanline_len_old], -2
6807 dunkaist 1514
 
8497 dunkaist 1515
        mov     ecx, [scanline_pixels_new]
1516
        mov     esi, [ebx + Image.Data]
1517
        mov     edi, [line_buffer]
1518
@@:
1519
        mov     ax, [esi]
1520
        mov     [edi], ax
1521
        add     esi, edx
1522
        add     edi, 2
1523
        sub     ecx, 1
1524
        jnz     @b
6807 dunkaist 1525
 
8497 dunkaist 1526
        mov     eax, [scanline_pixels_new]
1527
        mov     edi, [ebx + Image.Data]
1528
        lea     esi, [edi + 2]
1529
        mov     edx, [scanline_len_old]
1530
@@:
1531
        mov     ecx, edx
1532
        shr     ecx, 2
1533
        rep movsd
1534
        mov     ecx, edx
1535
        and     ecx, 3
1536
        rep movsb
1537
        add     esi, 1
1538
        sub     eax, 1
1539
        jnz     @b
6807 dunkaist 1540
 
8497 dunkaist 1541
        mov     eax, [scanline_len_new]
1542
        sub     [pixels_ptr], eax
1543
        mov     ecx, [scanline_pixels_new]
1544
        mov     esi, [line_buffer]
1545
        mov     edi, [pixels_ptr]
1546
        mov     edx, ecx
1547
        shr     ecx, 2
1548
        rep movsd
1549
        mov     ecx, edx
1550
        and     ecx, 3
1551
        rep movsb
6807 dunkaist 1552
 
8497 dunkaist 1553
        pop     ecx
1554
        jmp     .next_column_ccw_low1x
6807 dunkaist 1555
 
1556
.rotate_ccw32:
8497 dunkaist 1557
.next_column_ccw_low:
1558
        dec     ecx
1559
        js      .exchange_dims
1560
        push    ecx
6807 dunkaist 1561
 
8497 dunkaist 1562
        mov     edx, [scanline_len_old]
1563
        add     [scanline_len_old], -4
6807 dunkaist 1564
 
8497 dunkaist 1565
        mov     ecx, [scanline_pixels_new]
1566
        mov     esi, [ebx + Image.Data]
1567
        mov     edi, [line_buffer]
1568
@@:
1569
        mov     eax, [esi]
1570
        stosd
1571
        add     esi, edx
1572
        dec     ecx
1573
        jnz     @b
6807 dunkaist 1574
 
8497 dunkaist 1575
        mov     eax, [scanline_pixels_new]
1576
        mov     edi, [ebx + Image.Data]
1577
        lea     esi, [edi + 4]
1578
        mov     edx, [scanline_len_old]
1579
        shr     edx, 2
1580
@@:
1581
        mov     ecx, edx
1582
        rep movsd
1583
        add     esi, 4
1584
        dec     eax
1585
        jnz     @b
6807 dunkaist 1586
 
8497 dunkaist 1587
        mov     eax, [scanline_len_new]
1588
        sub     [pixels_ptr], eax
1589
        mov     ecx, [scanline_pixels_new]
1590
        mov     esi, [line_buffer]
1591
        mov     edi, [pixels_ptr]
1592
        rep movsd
6807 dunkaist 1593
 
8497 dunkaist 1594
        pop     ecx
1595
        jmp     .next_column_ccw_low
6807 dunkaist 1596
 
1597
.rotate_ccw8ig:
8497 dunkaist 1598
.next_column_ccw_low8ig:
1599
        dec     ecx
1600
        js      .exchange_dims
1601
        push    ecx
6807 dunkaist 1602
 
8497 dunkaist 1603
        mov     edx, [scanline_len_old]
1604
        add     [scanline_len_old], -1
6807 dunkaist 1605
 
8497 dunkaist 1606
        mov     ecx, [scanline_pixels_new]
1607
        mov     esi, [ebx + Image.Data]
1608
        mov     edi, [line_buffer]
1609
@@:
1610
        mov     al, [esi]
1611
        mov     [edi], al
1612
        add     esi, edx
1613
        add     edi, 1
1614
        sub     ecx, 1
1615
        jnz     @b
6807 dunkaist 1616
 
8497 dunkaist 1617
        mov     eax, [scanline_pixels_new]
1618
        mov     edi, [ebx + Image.Data]
1619
        lea     esi, [edi + 1]
1620
        mov     edx, [scanline_len_old]
1621
@@:
1622
        mov     ecx, edx
1623
        shr     ecx, 2
1624
        rep movsd
1625
        mov     ecx, edx
1626
        and     ecx, 3
1627
        rep movsb
1628
        add     esi, 1
1629
        sub     eax, 1
1630
        jnz     @b
6807 dunkaist 1631
 
8497 dunkaist 1632
        mov     eax, [scanline_len_new]
1633
        sub     [pixels_ptr], eax
1634
        mov     ecx, [scanline_pixels_new]
1635
        mov     esi, [line_buffer]
1636
        mov     edi, [pixels_ptr]
1637
        mov     edx, ecx
1638
        shr     ecx, 2
1639
        rep movsd
1640
        mov     ecx, edx
1641
        and     ecx, 3
1642
        rep movsb
6807 dunkaist 1643
 
8497 dunkaist 1644
        pop     ecx
1645
        jmp     .next_column_ccw_low8ig
6807 dunkaist 1646
 
1647
.rotate_ccw24:
8497 dunkaist 1648
.next_column_ccw_low24:
1649
        dec     ecx
1650
        js      .exchange_dims
1651
        push    ecx
6807 dunkaist 1652
 
8497 dunkaist 1653
        mov     edx, [scanline_len_old]
1654
        add     [scanline_len_old], -3
6807 dunkaist 1655
 
8497 dunkaist 1656
        mov     ecx, [scanline_pixels_new]
1657
        mov     esi, [ebx + Image.Data]
1658
        mov     edi, [line_buffer]
1659
@@:
1660
        mov     al, [esi]
1661
        mov     [edi], al
1662
        mov     al, [esi+1]
1663
        mov     [edi+1], al
1664
        mov     al, [esi+2]
1665
        mov     [edi+2], al
1666
        add     esi, edx
1667
        add     edi, 3
1668
        sub     ecx, 1
1669
        jnz     @b
6807 dunkaist 1670
 
8497 dunkaist 1671
        mov     eax, [scanline_pixels_new]
1672
        mov     edi, [ebx + Image.Data]
1673
        lea     esi, [edi + 3]
1674
        mov     edx, [scanline_len_old]
1675
@@:
1676
        mov     ecx, edx
1677
        shr     ecx, 2
1678
        rep movsd
1679
        mov     ecx, edx
1680
        and     ecx, 3
1681
        rep movsb
1682
        add     esi, 3
1683
        sub     eax, 1
1684
        jnz     @b
6807 dunkaist 1685
 
8497 dunkaist 1686
        mov     eax, [scanline_len_new]
1687
        sub     [pixels_ptr], eax
1688
        mov     ecx, eax
1689
        mov     esi, [line_buffer]
1690
        mov     edi, [pixels_ptr]
1691
        shr     ecx, 2
1692
        rep movsd
1693
        mov     ecx, eax
1694
        and     ecx, 3
1695
        rep movsb
6807 dunkaist 1696
 
8497 dunkaist 1697
        pop     ecx
1698
        jmp     .next_column_ccw_low24
6807 dunkaist 1699
 
1700
.rotate_ccw1:
8497 dunkaist 1701
        push    ecx edx
6807 dunkaist 1702
 
8497 dunkaist 1703
        mov     eax, [ebx + Image.Height]
1704
        add     eax, 7
1705
        shr     eax, 3
1706
        imul    eax, [ebx + Image.Width]
1707
        push    eax                             ; save new data size
6807 dunkaist 1708
 
8497 dunkaist 1709
        invoke  mem.alloc, eax
1710
        or      eax, eax
1711
        jz      .error
1712
        push    eax                             ; save pointer to new data
6807 dunkaist 1713
 
8497 dunkaist 1714
        mov     ecx, [ebx + Image.Width]
1715
        and     ecx, 7
1716
        neg     ecx
1717
        add     ecx, 8
1718
        and     ecx, 7
6807 dunkaist 1719
 
8497 dunkaist 1720
        mov     edi, eax
1721
        mov     esi, [ebx + Image.Data]
1722
        mov     eax, 7
1723
        mov     edx, [scanline_len_old]
1724
        dec     edx
1725
        add     esi, edx
6807 dunkaist 1726
 
8497 dunkaist 1727
.rotate_ccw1.begin:
1728
        bt      [esi], ecx
1729
        jc      .rotate_ccw1.one
1730
.rotate_ccw1.zero:
1731
        btr     [edi], eax
1732
        jmp     @f
1733
.rotate_ccw1.one:
1734
        bts     [edi], eax
1735
@@:
1736
        add     esi, [scanline_len_old]
1737
        dec     [scanline_pixels_new]
1738
        jz      .rotate_ccw1.end_of_line
1739
        sub     eax, 1
1740
        adc     edi, 0
1741
        and     eax, 7
1742
        jmp     .rotate_ccw1.begin
1743
.rotate_ccw1.end_of_line:
1744
        inc     edi
1745
        mov     eax, [ebx + Image.Height]
1746
        mov     [scanline_pixels_new], eax
1747
        mov     eax, 7
1748
        inc     ecx
1749
        and     ecx, 7
1750
        jz      @f
1751
        mov     esi, [ebx + Image.Data]
1752
        add     esi, edx
1753
        jmp     .rotate_ccw1.begin
1754
@@:
1755
        dec     edx
1756
        js      .rotate_ccw1.quit
1757
        mov     esi, [ebx + Image.Data]
1758
        add     esi, edx
1759
        jmp     .rotate_ccw1.begin
1760
.rotate_ccw1.quit:
1761
        pop     esi                             ; get pointer to new data
1762
        mov     edi, [ebx + Image.Data]
1763
        pop     ecx                             ; get new data size
1764
        rep movsb
1765
        invoke  mem.free, esi
1766
        pop     edx ecx
1767
        jmp     .exchange_dims
6807 dunkaist 1768
 
1769
 
1770
.rotate_ccw2i:
8497 dunkaist 1771
        push    ecx edx
6807 dunkaist 1772
 
8497 dunkaist 1773
        mov     eax, [ebx + Image.Height]
1774
        add     eax, 3
1775
        shr     eax, 2
1776
        imul    eax, [ebx + Image.Width]
1777
        push    eax                             ; save new data size
6807 dunkaist 1778
 
8497 dunkaist 1779
        invoke  mem.alloc, eax
1780
        or      eax, eax
1781
        jz      .error
1782
        push    eax                             ; save pointer to new data
6807 dunkaist 1783
 
8497 dunkaist 1784
        mov     ecx, [ebx + Image.Width]
1785
        and     ecx, 3
1786
        neg     ecx
1787
        add     ecx, 4
1788
        and     ecx, 3
6807 dunkaist 1789
 
8497 dunkaist 1790
        mov     edi, eax
1791
        mov     esi, [ebx + Image.Data]
1792
        mov     eax, 3
1793
        mov     edx, [scanline_len_old]
1794
        dec     edx
1795
        add     esi, edx
6807 dunkaist 1796
 
8497 dunkaist 1797
.rotate_ccw2i.begin:
1798
        push    ebx ecx
1799
        mov     ebx, 3
1800
        shl     ebx, cl
1801
        shl     ebx, cl
1802
        and     bl, [esi]
1803
        shr     ebx, cl
1804
        shr     ebx, cl
1805
        mov     bh, 3
1806
        mov     ecx, eax
1807
        shl     ebx, cl
1808
        shl     ebx, cl
1809
        not     bh
1810
        and     bh, [edi]
1811
        or      bl, bh
1812
        mov     [edi], bl
1813
        pop     ecx ebx
6807 dunkaist 1814
 
8497 dunkaist 1815
        add     esi, [scanline_len_old]
1816
        dec     [scanline_pixels_new]
1817
        jz      .rotate_ccw2i.end_of_line
1818
        sub     eax, 1
1819
        adc     edi, 0
1820
        and     eax, 3
1821
        jmp     .rotate_ccw2i.begin
1822
.rotate_ccw2i.end_of_line:
1823
        inc     edi
1824
        mov     eax, 3
1825
        mov     esi, [ebx + Image.Height]
1826
        mov     [scanline_pixels_new], esi
1827
        inc     ecx
1828
        and     ecx, 3
1829
        jz      @f
1830
        mov     esi, [ebx + Image.Data]
1831
        add     esi, edx
1832
        jmp     .rotate_ccw2i.begin
1833
@@:
1834
        dec     edx
1835
        js      .rotate_ccw2i.quit
1836
        mov     esi, [ebx + Image.Data]
1837
        add     esi, edx
1838
        jmp     .rotate_ccw2i.begin
1839
.rotate_ccw2i.quit:
1840
        pop     esi                             ; get pointer to new data
1841
        mov     edi, [ebx + Image.Data]
1842
        pop     ecx                             ; get new data size
1843
        rep movsb
1844
        invoke  mem.free, esi
1845
        pop     edx ecx
1846
        jmp     .exchange_dims
6807 dunkaist 1847
 
1848
 
1849
.rotate_ccw4i:
8497 dunkaist 1850
        push    ecx edx
6807 dunkaist 1851
 
8497 dunkaist 1852
        mov     eax, [ebx + Image.Height]
1853
        add     eax, 1
1854
        shr     eax, 1
1855
        imul    eax, [ebx + Image.Width]
1856
        push    eax                             ; save new data size
6807 dunkaist 1857
 
8497 dunkaist 1858
        invoke  mem.alloc, eax
1859
        or      eax, eax
1860
        jz      .error
1861
        push    eax                             ; save pointer to new data
6807 dunkaist 1862
 
8497 dunkaist 1863
        mov     ecx, [ebx + Image.Width]
1864
        and     ecx, 1
1865
        neg     ecx
1866
        add     ecx, 2
1867
        and     ecx, 1
6807 dunkaist 1868
 
8497 dunkaist 1869
        mov     edi, eax
1870
        mov     esi, [ebx + Image.Data]
1871
        mov     eax, 1
1872
        mov     edx, [scanline_len_old]
1873
        dec     edx
1874
        add     esi, edx
6807 dunkaist 1875
 
8497 dunkaist 1876
.rotate_ccw4i.begin:
1877
        push    ebx ecx
1878
        mov     ebx, 15
1879
        shl     ecx, 2
1880
        shl     ebx, cl
1881
        and     bl, [esi]
1882
        shr     ebx, cl
1883
        mov     bh, 15
1884
        mov     ecx, eax
1885
        shl     ecx, 2
1886
        shl     ebx, cl
1887
        not     bh
1888
        and     bh, [edi]
1889
        or      bl, bh
1890
        mov     [edi], bl
1891
        pop     ecx ebx
6807 dunkaist 1892
 
8497 dunkaist 1893
        add     esi, [scanline_len_old]
1894
        dec     [scanline_pixels_new]
1895
        jz      .rotate_ccw4i.end_of_line
1896
        sub     eax, 1
1897
        adc     edi, 0
1898
        and     eax, 1
1899
        jmp     .rotate_ccw4i.begin
1900
.rotate_ccw4i.end_of_line:
1901
        inc     edi
1902
        mov     eax, 1
1903
        mov     esi, [ebx + Image.Height]
1904
        mov     [scanline_pixels_new], esi
1905
        inc     ecx
1906
        and     ecx, 1
1907
        jz      @f
1908
        mov     esi, [ebx + Image.Data]
1909
        add     esi, edx
1910
        jmp     .rotate_ccw4i.begin
1911
@@:
1912
        dec     edx
1913
        js      .rotate_ccw4i.quit
1914
        mov     esi, [ebx + Image.Data]
1915
        add     esi, edx
1916
        jmp     .rotate_ccw4i.begin
1917
.rotate_ccw4i.quit:
1918
        pop     esi                             ; get pointer to new data
1919
        mov     edi, [ebx + Image.Data]
1920
        pop     ecx                             ; get new data size
1921
        rep movsb
1922
        invoke  mem.free, esi
1923
        pop     edx ecx
1924
        jmp     .exchange_dims
6807 dunkaist 1925
 
1926
 
1927
 
8497 dunkaist 1928
.rotate_cw_low:
1929
        mov     eax, [ebx + Image.Height]
1930
        mov     [scanline_pixels_new], eax
1931
        call    img._.get_scanline_len
1932
        mov     [scanline_len_new], eax
6807 dunkaist 1933
 
8497 dunkaist 1934
        invoke  mem.alloc, eax
1935
        or      eax, eax
1936
        jz      .error
1937
        mov     [line_buffer], eax
6807 dunkaist 1938
 
8497 dunkaist 1939
        mov     eax, [ebx + Image.Width]
1940
        mov     ecx, eax
1941
        call    img._.get_scanline_len
1942
        mov     [scanline_len_old], eax
6807 dunkaist 1943
 
8497 dunkaist 1944
        mov     eax, [scanline_len_new]
1945
        imul    eax, ecx
1946
        add     eax, [ebx + Image.Data]
1947
        mov     [pixels_ptr], eax
6807 dunkaist 1948
 
8497 dunkaist 1949
        cmp     [ebx + Image.Type], Image.bpp1
1950
        jz      .rotate_cw1
1951
        cmp     [ebx + Image.Type], Image.bpp2i
1952
        jz      .rotate_cw2i
1953
        cmp     [ebx + Image.Type], Image.bpp4i
1954
        jz      .rotate_cw4i
1955
        cmp     [ebx + Image.Type], Image.bpp8i
1956
        jz      .rotate_cw8ig
1957
        cmp     [ebx + Image.Type], Image.bpp8g
1958
        jz      .rotate_cw8ig
1959
        cmp     [ebx + Image.Type], Image.bpp24
1960
        jz      .rotate_cw24
1961
        cmp     [ebx + Image.Type], Image.bpp32
1962
        jz      .rotate_cw32
6807 dunkaist 1963
 
8497 dunkaist 1964
.next_column_cw_low1x:
1965
        dec     ecx
1966
        js      .exchange_dims
1967
        push    ecx
6807 dunkaist 1968
 
8497 dunkaist 1969
        mov     edx, [scanline_len_old]
1970
        add     [scanline_len_old], -2
6807 dunkaist 1971
 
8497 dunkaist 1972
        mov     ecx, [scanline_pixels_new]
1973
        mov     esi, [pixels_ptr]
1974
        add     esi, -2
1975
        mov     edi, [line_buffer]
1976
@@:
1977
        mov     ax, [esi]
1978
        mov     [edi], ax
1979
        sub     esi, edx
1980
        add     edi, 2
1981
        sub     ecx, 1
1982
        jnz     @b
6807 dunkaist 1983
 
8497 dunkaist 1984
        mov     eax, [scanline_pixels_new]
1985
        dec     eax
1986
        mov     edi, [ebx + Image.Data]
1987
        add     edi, [scanline_len_old]
1988
        lea     esi, [edi + 2]
1989
        mov     edx, [scanline_len_old]
1990
@@:
1991
        mov     ecx, edx
1992
        shr     ecx, 2
1993
        rep movsd
1994
        mov     ecx, edx
1995
        and     ecx, 3
1996
        rep movsb
1997
        add     esi, 3
1998
        sub     eax, 1
1999
        jnz     @b
6807 dunkaist 2000
 
8497 dunkaist 2001
        mov     eax, [scanline_len_new]
2002
        sub     [pixels_ptr], eax
2003
        mov     ecx, eax
2004
        mov     esi, [line_buffer]
2005
        mov     edi, [pixels_ptr]
2006
        shr     ecx, 2
2007
        rep movsd
2008
        mov     ecx, eax
2009
        and     ecx, 3
2010
        rep movsb
6807 dunkaist 2011
 
8497 dunkaist 2012
        pop     ecx
2013
        jmp     .next_column_cw_low1x
6807 dunkaist 2014
 
2015
.rotate_cw32:
8497 dunkaist 2016
.next_column_cw_low:
2017
        dec     ecx
2018
        js      .exchange_dims
2019
        push    ecx
6807 dunkaist 2020
 
8497 dunkaist 2021
        mov     edx, [scanline_len_old]
2022
        add     [scanline_len_old], -4
6807 dunkaist 2023
 
8497 dunkaist 2024
        mov     ecx, [scanline_pixels_new]
2025
        mov     esi, [pixels_ptr]
2026
        add     esi, -4
2027
        mov     edi, [line_buffer]
2028
@@:
2029
        mov     eax, [esi]
2030
        stosd
2031
        sub     esi, edx
2032
        dec     ecx
2033
        jnz     @b
6807 dunkaist 2034
 
8497 dunkaist 2035
        mov     eax, [scanline_pixels_new]
2036
        dec     eax
2037
        mov     edi, [ebx + Image.Data]
2038
        add     edi, [scanline_len_old]
2039
        lea     esi, [edi + 4]
2040
        mov     edx, [scanline_len_old]
2041
        shr     edx, 2
2042
@@:
2043
        mov     ecx, edx
2044
        rep movsd
2045
        add     esi, 4
2046
        dec     eax
2047
        jnz     @b
6807 dunkaist 2048
 
8497 dunkaist 2049
        mov     eax, [scanline_len_new]
2050
        sub     [pixels_ptr], eax
2051
        mov     ecx, [scanline_pixels_new]
2052
        mov     esi, [line_buffer]
2053
        mov     edi, [pixels_ptr]
2054
        rep movsd
6807 dunkaist 2055
 
8497 dunkaist 2056
        pop     ecx
2057
        jmp     .next_column_cw_low
6807 dunkaist 2058
 
2059
.rotate_cw8ig:
8497 dunkaist 2060
.next_column_cw_low8ig:
2061
        dec     ecx
2062
        js      .exchange_dims
2063
        push    ecx
6807 dunkaist 2064
 
8497 dunkaist 2065
        mov     edx, [scanline_len_old]
2066
        add     [scanline_len_old], -1
6807 dunkaist 2067
 
8497 dunkaist 2068
        mov     ecx, [scanline_pixels_new]
2069
        mov     esi, [pixels_ptr]
2070
        add     esi, -1
2071
        mov     edi, [line_buffer]
2072
@@:
2073
        mov     al, [esi]
2074
        mov     [edi], al
2075
        sub     esi, edx
2076
        add     edi, 1
2077
        sub     ecx, 1
2078
        jnz     @b
6807 dunkaist 2079
 
8497 dunkaist 2080
        mov     eax, [scanline_pixels_new]
2081
        dec     eax
2082
        mov     edi, [ebx + Image.Data]
2083
        add     edi, [scanline_len_old]
2084
        lea     esi, [edi + 1]
2085
        mov     edx, [scanline_len_old]
2086
@@:
2087
        mov     ecx, edx
2088
        shr     ecx, 2
2089
        rep movsd
2090
        mov     ecx, edx
2091
        and     ecx, 3
2092
        rep movsb
2093
        add     esi, 1
2094
        sub     eax, 1
2095
        jnz     @b
6807 dunkaist 2096
 
8497 dunkaist 2097
        mov     eax, [scanline_len_new]
2098
        sub     [pixels_ptr], eax
2099
        mov     ecx, eax
2100
        mov     esi, [line_buffer]
2101
        mov     edi, [pixels_ptr]
2102
        shr     ecx, 2
2103
        rep movsd
2104
        mov     ecx, eax
2105
        and     ecx, 3
2106
        rep movsb
6807 dunkaist 2107
 
8497 dunkaist 2108
        pop     ecx
2109
        jmp     .next_column_cw_low8ig
6807 dunkaist 2110
 
2111
.rotate_cw24:
8497 dunkaist 2112
.next_column_cw_low24:
2113
        dec     ecx
2114
        js      .exchange_dims
2115
        push    ecx
6807 dunkaist 2116
 
8497 dunkaist 2117
        mov     edx, [scanline_len_old]
2118
        add     [scanline_len_old], -3
6807 dunkaist 2119
 
8497 dunkaist 2120
        mov     ecx, [scanline_pixels_new]
2121
        mov     esi, [pixels_ptr]
2122
        add     esi, -3
2123
        mov     edi, [line_buffer]
2124
@@:
2125
        mov     al, [esi]
2126
        mov     [edi], al
2127
        mov     al, [esi+1]
2128
        mov     [edi+1], al
2129
        mov     al, [esi+2]
2130
        mov     [edi+2], al
2131
        sub     esi, edx
2132
        add     edi, 3
2133
        sub     ecx, 1
2134
        jnz     @b
6807 dunkaist 2135
 
8497 dunkaist 2136
        mov     eax, [scanline_pixels_new]
2137
        dec     eax
2138
        mov     edi, [ebx + Image.Data]
2139
        add     edi, [scanline_len_old]
2140
        lea     esi, [edi + 3]
2141
        mov     edx, [scanline_len_old]
2142
@@:
2143
        mov     ecx, edx
2144
        shr     ecx, 2
2145
        rep movsd
2146
        mov     ecx, edx
2147
        and     ecx, 3
2148
        rep movsb
2149
        add     esi, 3
2150
        sub     eax, 1
2151
        jnz     @b
6807 dunkaist 2152
 
8497 dunkaist 2153
        mov     eax, [scanline_len_new]
2154
        sub     [pixels_ptr], eax
2155
        mov     ecx, eax
2156
        mov     esi, [line_buffer]
2157
        mov     edi, [pixels_ptr]
2158
        shr     ecx, 2
2159
        rep movsd
2160
        mov     ecx, eax
2161
        and     ecx, 3
2162
        rep movsb
6807 dunkaist 2163
 
8497 dunkaist 2164
        pop     ecx
2165
        jmp     .next_column_cw_low24
6807 dunkaist 2166
 
2167
 
2168
.rotate_cw1:
8497 dunkaist 2169
        push    ecx edx
6807 dunkaist 2170
 
8497 dunkaist 2171
        mov     eax, [ebx + Image.Height]
2172
        add     eax, 7
2173
        shr     eax, 3
2174
        imul    [ebx + Image.Width]
2175
        push    eax                             ; save new data size
6807 dunkaist 2176
 
8497 dunkaist 2177
        invoke  mem.alloc, eax
2178
        or      eax, eax
2179
        jz      .error
2180
        push    eax                             ; save pointer to new data
6807 dunkaist 2181
 
8497 dunkaist 2182
        mov     edi, eax
2183
        mov     esi, [ebx + Image.Data]
2184
        mov     eax, [ebx + Image.Height]
2185
        dec     eax
2186
        imul    eax, [scanline_len_old]
2187
        add     esi, eax
2188
        mov     eax, 7
2189
        mov     ecx, 7
2190
        mov     edx, 0
6807 dunkaist 2191
 
8497 dunkaist 2192
.rotate_cw1.begin:
2193
        bt      [esi], ecx
2194
        jc      .rotate_cw1.one
2195
.rotate_cw1.zero:
2196
        btr     [edi], eax
2197
        jmp     @f
2198
.rotate_cw1.one:
2199
        bts     [edi], eax
2200
@@:
2201
        sub     esi, [scanline_len_old]
2202
        dec     [scanline_pixels_new]
2203
        jz      .rotate_cw1.end_of_line
2204
        sub     eax, 1
2205
        adc     edi, 0
2206
        and     eax, 7
2207
        jmp     .rotate_cw1.begin
2208
.rotate_cw1.end_of_line:
2209
        inc     edi
2210
        mov     eax, [ebx + Image.Height]
2211
        mov     [scanline_pixels_new], eax
2212
        mov     eax, 7
2213
        dec     ecx
2214
        jns     @f
2215
        mov     ecx, 7
2216
        inc     edx
2217
        cmp     edx, [scanline_len_old]
2218
        je      .rotate_cw1.quit
2219
@@:
2220
        mov     esi, [ebx + Image.Height]
2221
        dec     esi
2222
        imul    esi, [scanline_len_old]
2223
        add     esi, [ebx + Image.Data]
2224
        add     esi, edx
2225
        jmp     .rotate_cw1.begin
2226
.rotate_cw1.quit:
2227
        pop     eax                             ; get pointer to new data
2228
        mov     esi, eax
2229
        mov     edi, [ebx + Image.Data]
2230
        pop     ecx                             ; get new data size
2231
        rep movsb
2232
        invoke  mem.free, eax
2233
        pop     edx ecx
2234
        jmp     .exchange_dims
6807 dunkaist 2235
 
2236
 
2237
.rotate_cw2i:
8497 dunkaist 2238
        push    ecx edx
6807 dunkaist 2239
 
8497 dunkaist 2240
        mov     eax, [ebx + Image.Height]
2241
        add     eax, 3
2242
        shr     eax, 2
2243
        imul    [ebx + Image.Width]
2244
        push    eax                             ; save new data size
6807 dunkaist 2245
 
8497 dunkaist 2246
        invoke  mem.alloc, eax
2247
        or      eax, eax
2248
        jz      .error
2249
        push    eax                             ; save pointer to new data
6807 dunkaist 2250
 
8497 dunkaist 2251
        mov     edi, eax
2252
        mov     esi, [ebx + Image.Data]
2253
        mov     eax, [ebx + Image.Height]
2254
        dec     eax
2255
        imul    eax, [scanline_len_old]
2256
        add     esi, eax
2257
        mov     eax, 3
2258
        mov     ecx, 3
2259
        mov     edx, 0
6807 dunkaist 2260
 
8497 dunkaist 2261
.rotate_cw2i.begin:
2262
        push    ebx ecx
2263
        mov     ebx, 3
2264
        shl     ebx, cl
2265
        shl     ebx, cl
2266
        and     bl, [esi]
2267
        shr     ebx, cl
2268
        shr     ebx, cl
2269
        mov     bh, 3
2270
        mov     ecx, eax
2271
        shl     ebx, cl
2272
        shl     ebx, cl
2273
        not     bh
2274
        and     bh, [edi]
2275
        or      bl, bh
2276
        mov     [edi], bl
2277
        pop     ecx ebx
6807 dunkaist 2278
 
8497 dunkaist 2279
        sub     esi, [scanline_len_old]
2280
        dec     [scanline_pixels_new]
2281
        jz      .rotate_cw2i.end_of_line
2282
        sub     eax, 1
2283
        adc     edi, 0
2284
        and     eax, 3
2285
        jmp     .rotate_cw2i.begin
2286
.rotate_cw2i.end_of_line:
2287
        inc     edi
2288
        mov     eax, [ebx + Image.Height]
2289
        mov     [scanline_pixels_new], eax
2290
        mov     eax, 3
2291
        dec     ecx
2292
        jns     @f
2293
        mov     ecx, 3
2294
        inc     edx
2295
        cmp     edx, [scanline_len_old]
2296
        je      .rotate_cw2i.quit
2297
@@:
2298
        mov     esi, [ebx + Image.Height]
2299
        dec     esi
2300
        imul    esi, [scanline_len_old]
2301
        add     esi, [ebx + Image.Data]
2302
        add     esi, edx
2303
        jmp     .rotate_cw2i.begin
2304
.rotate_cw2i.quit:
2305
        pop     eax                             ; get pointer to new data
2306
        mov     esi, eax
2307
        mov     edi, [ebx + Image.Data]
2308
        pop     ecx                             ; get new data size
2309
        rep movsb
2310
        invoke  mem.free, eax
2311
        pop     edx ecx
2312
        jmp     .exchange_dims
6807 dunkaist 2313
 
2314
 
2315
.rotate_cw4i:
8497 dunkaist 2316
        push    ecx edx
6807 dunkaist 2317
 
8497 dunkaist 2318
        mov     eax, [ebx + Image.Height]
2319
        add     eax, 1
2320
        shr     eax, 1
2321
        imul    [ebx + Image.Width]
2322
        push    eax                             ; save new data size
6807 dunkaist 2323
 
8497 dunkaist 2324
        invoke  mem.alloc, eax
2325
        or      eax, eax
2326
        jz      .error
2327
        push    eax                             ; save pointer to new data
6807 dunkaist 2328
 
8497 dunkaist 2329
        mov     edi, eax
2330
        mov     esi, [ebx + Image.Data]
2331
        mov     eax, [ebx + Image.Height]
2332
        dec     eax
2333
        imul    eax, [scanline_len_old]
2334
        add     esi, eax
2335
        mov     eax, 1
2336
        mov     ecx, 1
2337
        mov     edx, 0
6807 dunkaist 2338
 
8497 dunkaist 2339
.rotate_cw4i.begin:
2340
        push    ebx ecx
2341
        mov     ebx, 15
2342
        shl     ecx, 2
2343
        shl     ebx, cl
2344
        and     bl, [esi]
2345
        shr     ebx, cl
2346
        mov     bh, 15
2347
        mov     ecx, eax
2348
        shl     ecx, 2
2349
        shl     ebx, cl
2350
        not     bh
2351
        and     bh, [edi]
2352
        or      bl, bh
2353
        mov     [edi], bl
2354
        pop     ecx ebx
6807 dunkaist 2355
 
8497 dunkaist 2356
        sub     esi, [scanline_len_old]
2357
        dec     [scanline_pixels_new]
2358
        jz      .rotate_cw4i.end_of_line
2359
        sub     eax, 1
2360
        adc     edi, 0
2361
        and     eax, 1
2362
        jmp     .rotate_cw4i.begin
2363
.rotate_cw4i.end_of_line:
2364
        inc     edi
2365
        mov     eax, [ebx + Image.Height]
2366
        mov     [scanline_pixels_new], eax
2367
        mov     eax, 1
2368
        dec     ecx
2369
        jns     @f
2370
        mov     ecx, 1
2371
        inc     edx
2372
        cmp     edx, [scanline_len_old]
2373
        je      .rotate_cw4i.quit
2374
@@:
2375
        mov     esi, [ebx + Image.Height]
2376
        dec     esi
2377
        imul    esi, [scanline_len_old]
2378
        add     esi, [ebx + Image.Data]
2379
        add     esi, edx
2380
        jmp     .rotate_cw4i.begin
2381
.rotate_cw4i.quit:
2382
        pop     eax                             ; get pointer to new data
2383
        mov     esi, eax
2384
        mov     edi, [ebx + Image.Data]
2385
        pop     ecx                             ; get new data size
2386
        rep movsb
2387
        invoke  mem.free, eax
2388
        pop     edx ecx
2389
        jmp     .exchange_dims
6807 dunkaist 2390
 
2391
 
8497 dunkaist 2392
.flip:
2393
        stdcall img.flip.layer, [_img], FLIP_VERTICAL
2394
        test    eax, eax
2395
        jz      .error
2396
        jmp     .exit
6807 dunkaist 2397
 
8497 dunkaist 2398
.exchange_dims:
2399
        push    [ebx + Image.Width] [ebx + Image.Height]
2400
        pop     [ebx + Image.Width] [ebx + Image.Height]
6807 dunkaist 2401
 
8497 dunkaist 2402
.exit:
2403
        invoke  mem.free, [line_buffer]
2404
        xor     eax, eax
2405
        inc     eax
2406
        pop     edi esi ebx
2407
        ret
6807 dunkaist 2408
 
8497 dunkaist 2409
.error:
2410
        invoke  mem.free, [line_buffer]
2411
        xor     eax, eax
2412
        pop     edi esi ebx
2413
        ret
6807 dunkaist 2414
endp
2415
 
8497 dunkaist 2416
;;============================================================================;;
2417
proc img.rotate _img, _rotate_kind ;//////////////////////////////////////////;;
2418
;;----------------------------------------------------------------------------;;
2419
;? Rotate all layers of image                                                 ;;
2420
;;----------------------------------------------------------------------------;;
2421
;> _img = pointer to image                                                    ;;
2422
;> _rotate_kind = one of ROTATE_* constants                                   ;;
2423
;;----------------------------------------------------------------------------;;
2424
;< eax = false / true                                                         ;;
2425
;;============================================================================;;
2426
        push    1
2427
        mov     ebx, [_img]
6807 dunkaist 2428
@@:
8497 dunkaist 2429
        mov     eax, [ebx + Image.Previous]
2430
        test    eax, eax
2431
        jz      .loop
2432
        mov     ebx, eax
2433
        jmp     @b
6807 dunkaist 2434
.loop:
8497 dunkaist 2435
        stdcall img.rotate.layer, ebx, [_rotate_kind]
2436
        test    eax, eax
2437
        jnz     @f
2438
        mov     byte [esp], 0
6807 dunkaist 2439
@@:
8497 dunkaist 2440
        mov     ebx, [ebx + Image.Next]
2441
        test    ebx, ebx
2442
        jnz     .loop
2443
        pop     eax
2444
        ret
6807 dunkaist 2445
endp
2446
 
8497 dunkaist 2447
;;============================================================================;;
2448
proc img.draw _img, _x, _y, _width, _height, _xpos, _ypos ;///////////////////;;
2449
;;----------------------------------------------------------------------------;;
2450
;? Draw image in the window                                                   ;;
2451
;;----------------------------------------------------------------------------;;
2452
;> _img = pointer to image                                                    ;;
2453
;>_x = x-coordinate in the window                                             ;;
2454
;>_y = y-coordinate in the window                                             ;;
2455
;>_width = maximum width to draw                                              ;;
2456
;>_height = maximum height to draw                                            ;;
2457
;>_xpos = offset in image by x-axis                                           ;;
2458
;>_ypos = offset in image by y-axis                                           ;;
2459
;;----------------------------------------------------------------------------;;
2460
;< no return value                                                            ;;
2461
;;============================================================================;;
2462
        push    ebx esi edi
2463
        mov     ebx, [_img]
2464
        stdcall img._.validate, ebx
2465
        test    eax, eax
2466
        jnz     .done
2467
        mov     ecx, [ebx + Image.Width]
2468
        sub     ecx, [_xpos]
2469
        jbe     .done
2470
        cmp     ecx, [_width]
2471
        jb      @f
2472
        mov     ecx, [_width]
6807 dunkaist 2473
@@:
8497 dunkaist 2474
        mov     edx, [ebx + Image.Height]
2475
        sub     edx, [_ypos]
2476
        jbe     .done
2477
        cmp     edx, [_height]
2478
        jb      @f
2479
        mov     edx, [_height]
6807 dunkaist 2480
@@:
8497 dunkaist 2481
        mov     eax, [ebx + Image.Width]
2482
        sub     eax, ecx
2483
        call    img._.get_scanline_len
2484
        shl     ecx, 16
2485
        add     ecx, edx
2486
        push    eax
2487
        mov     eax, [ebx + Image.Width]
2488
        imul    eax, [_ypos]
2489
        add     eax, [_xpos]
2490
        call    img._.get_scanline_len
2491
        add     eax, [ebx + Image.Data]
2492
        mov     edx, [_x - 2]
2493
        mov     dx, word [_y]
2494
        mov     esi, [ebx + Image.Type]
2495
        mov     esi, [type2bpp + (esi-1)*4]
2496
        mov     edi, [ebx + Image.Palette]
2497
        xchg    eax, ebx
2498
        pop     eax
2499
        push    ebp
2500
        push    65
2501
        pop     ebp
2502
        xchg    eax, ebp
2503
        int     40h
2504
        pop     ebp
6807 dunkaist 2505
.done:
8497 dunkaist 2506
        pop     edi esi ebx
2507
        ret
6807 dunkaist 2508
endp
2509
 
2510
 
2511
align 4
2512
img.formats_table:
8497 dunkaist 2513
  .bmp  dd LIBIMG_FORMAT_BMP,  img.is.bmp,  img.decode.bmp,     img.encode.bmp, 1 + (1 SHL Image.bpp24) + (1 SHL Image.bpp32)
2514
  .ico  dd LIBIMG_FORMAT_ICO,  img.is.ico,  img.decode.ico_cur, img.encode.ico, 0
2515
  .cur  dd LIBIMG_FORMAT_CUR,  img.is.cur,  img.decode.ico_cur, img.encode.cur, 0
2516
  .gif  dd LIBIMG_FORMAT_GIF,  img.is.gif,  img.decode.gif,     img.encode.gif, 0
2517
  .png  dd LIBIMG_FORMAT_PNG,  img.is.png,  img.decode.png,     img.encode.png, 1 + (1 SHL Image.bpp24)
2518
  .jpg  dd LIBIMG_FORMAT_JPEG, img.is.jpg,  img.decode.jpg,     img.encode.jpg, 0
2519
  .tga  dd LIBIMG_FORMAT_TGA,  img.is.tga,  img.decode.tga,     img.encode.tga, 0
2520
  .pcx  dd LIBIMG_FORMAT_PCX,  img.is.pcx,  img.decode.pcx,     img.encode.pcx, 0
2521
  .xcf  dd LIBIMG_FORMAT_XCF,  img.is.xcf,  img.decode.xcf,     img.encode.xcf, 0
2522
  .tiff dd LIBIMG_FORMAT_TIFF, img.is.tiff, img.decode.tiff,    img.encode.tiff,0
2523
  .pnm  dd LIBIMG_FORMAT_PNM,  img.is.pnm,  img.decode.pnm,     img.encode.pnm, 1 + (1 SHL Image.bpp1) + (1 SHL Image.bpp8g) + (1 SHL Image.bpp24)
2524
  .wbmp dd LIBIMG_FORMAT_WBMP, img.is.wbmp, img.decode.wbmp,    img.encode.wbmp,0
2525
  .xbm  dd LIBIMG_FORMAT_XBM,  img.is.xbm,  img.decode.xbm,     img.encode.xbm, 0
2526
  .z80  dd LIBIMG_FORMAT_Z80,  img.is.z80,  img.decode.z80,     img.encode.z80, 0 ;this must be the last entry as there are no signatures in z80 screens at all
2527
        dd 0
6807 dunkaist 2528
 
8497 dunkaist 2529
;;============================================================================;;
2530
;;////////////////////////////////////////////////////////////////////////////;;
2531
;;============================================================================;;
2532
;! Below are private procs you should never call directly from your code      ;;
2533
;;============================================================================;;
2534
;;////////////////////////////////////////////////////////////////////////////;;
2535
;;============================================================================;;
6807 dunkaist 2536
 
2537
 
8497 dunkaist 2538
;;============================================================================;;
2539
proc img._.validate, _img ;///////////////////////////////////////////////////;;
2540
;;----------------------------------------------------------------------------;;
2541
;? --- TBD ---                                                                ;;
2542
;;----------------------------------------------------------------------------;;
2543
;> --- TBD ---                                                                ;;
2544
;;----------------------------------------------------------------------------;;
2545
;< --- TBD ---                                                                ;;
2546
;;============================================================================;;
2547
        xor     eax, eax
2548
        ret
6807 dunkaist 2549
endp
2550
 
8497 dunkaist 2551
;;============================================================================;;
2552
proc img._.new ;//////////////////////////////////////////////////////////////;;
2553
;;----------------------------------------------------------------------------;;
2554
;? --- TBD ---                                                                ;;
2555
;;----------------------------------------------------------------------------;;
2556
;> --- TBD ---                                                                ;;
2557
;;----------------------------------------------------------------------------;;
2558
;< eax = 0 / pointer to image                                                 ;;
2559
;;============================================================================;;
2560
        invoke  mem.alloc, sizeof.Image
2561
        test    eax, eax
2562
        jz      @f
2563
        push    ecx
2564
        xor     ecx, ecx
2565
        mov     [eax + Image.Data], ecx
2566
        mov     [eax + Image.Type], ecx
2567
        mov     [eax + Image.Flags], ecx
2568
        mov     [eax + Image.Extended], ecx
2569
        mov     [eax + Image.Previous], ecx
2570
        mov     [eax + Image.Next], ecx
2571
        pop     ecx
6807 dunkaist 2572
@@:
8497 dunkaist 2573
        ret
6807 dunkaist 2574
endp
2575
 
8497 dunkaist 2576
;;============================================================================;;
2577
proc img._.delete _img ;//////////////////////////////////////////////////////;;
2578
;;----------------------------------------------------------------------------;;
2579
;? --- TBD ---                                                                ;;
2580
;;----------------------------------------------------------------------------;;
2581
;> --- TBD ---                                                                ;;
2582
;;----------------------------------------------------------------------------;;
2583
;< eax = false / true                                                         ;;
2584
;;============================================================================;;
2585
        push    edx
2586
        mov     edx, [_img]
2587
        cmp     [edx + Image.Data], 0
2588
        je      @f
2589
        invoke  mem.free, [edx + Image.Data]
2590
@@:
2591
        cmp     [edx + Image.Extended], 0
2592
        je      @f
2593
        invoke  mem.free, [edx + Image.Extended]
2594
@@:
2595
        invoke  mem.free, edx
2596
        pop     edx
2597
        ret
6807 dunkaist 2598
endp
2599
 
8497 dunkaist 2600
;;============================================================================;;
2601
proc img.resize_data _img, _width, _height ;//////////////////////////////////;;
2602
;;----------------------------------------------------------------------------;;
2603
;? Resize data block of image. New size is calculated from _width and _height ;;
2604
;? params and internal Image.Type value. All the internal fields are updated  ;;
2605
;? iff succeeded. This function does not scale images, use img.scale if you   ;;
2606
;? need to.                                                                   ;;
2607
;;----------------------------------------------------------------------------;;
2608
;> _img = pointer to image                                                    ;;
2609
;> _width = new width                                                         ;;
2610
;> _height = new height                                                       ;;
2611
;;----------------------------------------------------------------------------;;
2612
;< eax = 0 (fail) / pointer to the new pixels data                            ;;
2613
;;============================================================================;;
2614
        push    ebx esi
2615
        mov     ebx, [_img]
2616
        mov     eax, [_height]
6807 dunkaist 2617
; our memory is limited, [_width]*[_height] must not overflow
2618
; image with width or height greater than 65535 is most likely bogus
8497 dunkaist 2619
        cmp     word [_width+2], 0
2620
        jnz     .error
2621
        cmp     word [_height+2], 0
2622
        jnz     .error
2623
        imul    eax, [_width]
2624
        test    eax, eax
2625
        jz      .error
2626
        cmp     [ebx + Image.Type], Image.bpp1
2627
        jz      .bpp1
2628
        cmp     [ebx + Image.Type], Image.bpp2i
2629
        jz      .bpp2i
2630
        cmp     [ebx + Image.Type], Image.bpp4i
2631
        jz      .bpp4i
2632
        cmp     [ebx + Image.Type], Image.bpp8i
2633
        jz      .bpp8i
2634
        cmp     [ebx + Image.Type], Image.bpp8g
2635
        jz      .bpp8g
2636
        cmp     [ebx + Image.Type], Image.bpp8a
2637
        jz      .bpp8a
2638
        cmp     [ebx + Image.Type], Image.bpp24
2639
        jz      .bpp24
6807 dunkaist 2640
.bpp32:
8497 dunkaist 2641
        shl     eax, 2
2642
        jmp     @f
6807 dunkaist 2643
.bpp24:
8497 dunkaist 2644
        lea     eax, [eax*3]
2645
        jmp     @f
6807 dunkaist 2646
.bpp8i:
8497 dunkaist 2647
        add     eax, 256*4  ; for palette
6807 dunkaist 2648
.bpp8g:
8497 dunkaist 2649
        jmp     @f
6807 dunkaist 2650
.bpp8a:
8497 dunkaist 2651
        shl     eax, 1
2652
        jmp     @f
6807 dunkaist 2653
.bpp4i:
8497 dunkaist 2654
        mov     eax, [_width]
2655
        add     eax, 1
2656
        shr     eax, 1
2657
        imul    eax, [_height]
2658
        mov     ecx, eax
2659
        mov     eax, [_height]
2660
        add     eax, 1
2661
        shr     eax, 1
2662
        imul    eax, [_width]
2663
        cmp     eax, ecx
2664
        jge     .bpp4i.skip
2665
        mov     eax, ecx
2666
.bpp4i.skip:
2667
        add     eax, 16*4    ; for palette
2668
        jmp     @f
6807 dunkaist 2669
.bpp2i:
8497 dunkaist 2670
        mov     eax, [_width]
2671
        add     eax, 3
2672
        shr     eax, 2
2673
        imul    eax, [_height]
2674
        mov     ecx, eax
2675
        mov     eax, [_height]
2676
        add     eax, 3
2677
        shr     eax, 2
2678
        imul    eax, [_width]
2679
        cmp     eax, ecx
2680
        jge     .bpp2i.skip
2681
        mov     eax, ecx
2682
.bpp2i.skip:
2683
        add     eax, 4*4    ; for palette
2684
        jmp     @f
6807 dunkaist 2685
.bpp1:
8497 dunkaist 2686
        mov     eax, [_width]
2687
        add     eax, 7
2688
        shr     eax, 3
2689
        imul    eax, [_height]
2690
        mov     ecx, eax
2691
        mov     eax, [_height]
2692
        add     eax, 7
2693
        shr     eax, 3
2694
        imul    eax, [_width]
2695
        cmp     eax, ecx
2696
        jge     .bpp1.skip
2697
        mov     eax, ecx
2698
.bpp1.skip:
6807 dunkaist 2699
 
8497 dunkaist 2700
        add     eax, 2*4    ; for palette
6807 dunkaist 2701
@@:
8497 dunkaist 2702
        mov     esi, eax
2703
        invoke  mem.realloc, [ebx + Image.Data], eax
2704
        or      eax, eax
2705
        jz      .error
6807 dunkaist 2706
 
8497 dunkaist 2707
        mov     [ebx + Image.Data], eax
2708
        push    [_width]
2709
        pop     [ebx + Image.Width]
2710
        push    [_height]
2711
        pop     [ebx + Image.Height]
2712
        cmp     [ebx + Image.Type], Image.bpp8i
2713
        jnz     @f
2714
        lea     esi, [eax + esi - 256*4]
2715
        mov     [ebx + Image.Palette], esi
2716
        jmp     .ret
6807 dunkaist 2717
@@:
8497 dunkaist 2718
        cmp     [ebx + Image.Type], Image.bpp1
2719
        jnz     @f
2720
        lea     esi, [eax + esi - 2*4]
2721
        mov     [ebx + Image.Palette], esi
2722
        jmp     .ret
6807 dunkaist 2723
@@:
8497 dunkaist 2724
        cmp     [ebx + Image.Type], Image.bpp2i
2725
        jnz     @f
2726
        lea     esi, [eax + esi - 4*4]
2727
        mov     [ebx + Image.Palette], esi
2728
        jmp     .ret
6807 dunkaist 2729
@@:
8497 dunkaist 2730
        cmp     [ebx + Image.Type], Image.bpp4i
2731
        jnz     .ret
2732
        lea     esi, [eax + esi - 16*4]
2733
        mov     [ebx + Image.Palette], esi
2734
        jmp     .ret
6807 dunkaist 2735
 
2736
  .error:
8497 dunkaist 2737
        xor     eax, eax
6807 dunkaist 2738
  .ret:
8497 dunkaist 2739
        pop     esi ebx
2740
        ret
6807 dunkaist 2741
endp
2742
 
8497 dunkaist 2743
;;============================================================================;;
2744
img._.get_scanline_len: ;/////////////////////////////////////////////////////;;
2745
;;----------------------------------------------------------------------------;;
2746
;? Get scanline length of image in bytes                                      ;;
2747
;;----------------------------------------------------------------------------;;
2748
;> eax = width of image in pixels                                             ;;
2749
;> ebx = image                                                                ;;
2750
;;----------------------------------------------------------------------------;;
2751
;< eax = scanline length in bytes                                             ;;
2752
;;============================================================================;;
2753
        cmp     [ebx + Image.Type], Image.bpp1
2754
        jz      .bpp1.1
2755
        cmp     [ebx + Image.Type], Image.bpp2i
2756
        jz      .bpp2i.1
2757
        cmp     [ebx + Image.Type], Image.bpp4i
2758
        jz      .bpp4i.1
2759
        cmp     [ebx + Image.Type], Image.bpp8i
2760
        jz      .bpp8.1
2761
        cmp     [ebx + Image.Type], Image.bpp8g
2762
        jz      .bpp8.1
2763
        cmp     [ebx + Image.Type], Image.bpp8a
2764
        jz      .bpp8a.1
2765
        cmp     [ebx + Image.Type], Image.bpp24
2766
        jz      .bpp24.1
2767
        add     eax, eax
2768
        cmp     [ebx + Image.Type], Image.bpp32
2769
        jnz     .quit
2770
        add     eax, eax
2771
        jmp     .quit
6807 dunkaist 2772
.bpp24.1:
8497 dunkaist 2773
        lea     eax, [eax*3]
2774
        jmp     .quit
6807 dunkaist 2775
.bpp1.1:
8497 dunkaist 2776
        add     eax, 7
2777
        shr     eax, 3
2778
        jmp     .quit
6807 dunkaist 2779
.bpp2i.1:
8497 dunkaist 2780
        add     eax, 3
2781
        shr     eax, 2
2782
        jmp     .quit
6807 dunkaist 2783
.bpp4i.1:
8497 dunkaist 2784
        add     eax, 1
2785
        shr     eax, 1
2786
        jmp     .quit
6807 dunkaist 2787
.bpp8a.1:
8497 dunkaist 2788
        shl     eax, 1
6807 dunkaist 2789
.bpp8.1:
2790
.quit:
8497 dunkaist 2791
        ret
6807 dunkaist 2792
 
2793
 
8497 dunkaist 2794
;;============================================================================;;
2795
;;////////////////////////////////////////////////////////////////////////////;;
2796
;;============================================================================;;
2797
;! Below is private data you should never use directly from your code         ;;
2798
;;============================================================================;;
2799
;;////////////////////////////////////////////////////////////////////////////;;
2800
;;============================================================================;;
6807 dunkaist 2801
 
8341 dunkaist 2802
section '.data' data readable writable align 16
7735 dunkaist 2803
;include_debug_strings
7105 dunkaist 2804
 
6807 dunkaist 2805
align 4
8497 dunkaist 2806
type2bpp    dd  8, 24, 32, 15, 16, 1, 9, 2, 4
6807 dunkaist 2807
img._.do_rgb.handlers:
8497 dunkaist 2808
    dd  img._.do_rgb.bpp8i
2809
    dd  img._.do_rgb.bpp24
2810
    dd  img._.do_rgb.bpp32
2811
    dd  img._.do_rgb.bpp15.amd  ; can be overwritten in lib_init
2812
    dd  img._.do_rgb.bpp16.amd  ; can be overwritten in lib_init
2813
    dd  img._.do_rgb.bpp1
2814
    dd  img._.do_rgb.bpp8g
2815
    dd  img._.do_rgb.bpp2i
2816
    dd  img._.do_rgb.bpp4i
6807 dunkaist 2817
 
2818
img.flip.layer.handlers_horz:
8497 dunkaist 2819
    dd  img.flip.layer.bpp8ig_horz
2820
    dd  img.flip.layer.bpp24_horz
2821
    dd  img.flip.layer.bpp32_horz
2822
    dd  img.flip.layer.bpp1x_horz
2823
    dd  img.flip.layer.bpp1x_horz
2824
    dd  img.flip.layer.bpp1_horz
2825
    dd  img.flip.layer.bpp8ig_horz
2826
    dd  img.flip.layer.bpp2i_horz
2827
    dd  img.flip.layer.bpp4i_horz
6807 dunkaist 2828
 
8497 dunkaist 2829
;;============================================================================;;
2830
;;////////////////////////////////////////////////////////////////////////////;;
2831
;;============================================================================;;
2832
;! Exported functions section                                                 ;;
2833
;;============================================================================;;
2834
;;////////////////////////////////////////////////////////////////////////////;;
2835
;;============================================================================;;
6807 dunkaist 2836
 
2837
 
2838
align 4
2839
@EXPORT:
2840
 
8497 dunkaist 2841
export                                      \
2842
    lib_init           , 'lib_init'           , \
2843
    0x00050007         , 'version'            , \
2844
    img.is_img         , 'img_is_img'         , \
2845
    img.info           , 'img_info'           , \
6807 dunkaist 2846
    img.from_file      , 'img_from_file'      , \
8497 dunkaist 2847
    img.to_file        , 'img_to_file'        , \
6807 dunkaist 2848
    img.from_rgb       , 'img_from_rgb'       , \
8497 dunkaist 2849
    img.to_rgb         , 'img_to_rgb'         , \
2850
    img.to_rgb2        , 'img_to_rgb2'        , \
2851
    img.decode         , 'img_decode'         , \
2852
    img.encode         , 'img_encode'         , \
2853
    img.create         , 'img_create'         , \
2854
    img.destroy        , 'img_destroy'        , \
6807 dunkaist 2855
    img.destroy.layer  , 'img_destroy_layer'  , \
8497 dunkaist 2856
    img.count          , 'img_count'          , \
6807 dunkaist 2857
    img.lock_bits      , 'img_lock_bits'      , \
2858
    img.unlock_bits    , 'img_unlock_bits'    , \
8497 dunkaist 2859
    img.flip           , 'img_flip'           , \
6807 dunkaist 2860
    img.flip.layer     , 'img_flip_layer'     , \
8497 dunkaist 2861
    img.rotate         , 'img_rotate'         , \
6807 dunkaist 2862
    img.rotate.layer   , 'img_rotate_layer'   , \
8497 dunkaist 2863
    img.draw           , 'img_draw'           , \
2864
    img.scale          , 'img_scale'          , \
6807 dunkaist 2865
    img.get_scaled_size, 'img_get_scaled_size', \
8497 dunkaist 2866
    img.convert        , 'img_convert'        , \
2867
    img.blend          , 'img_blend'          , \
8395 dunkaist 2868
    img.resize_data    , 'img_resize_data'    , \
6807 dunkaist 2869
    img.formats_table  , 'img_formats_table'
2870
 
2871
; import from deflate unpacker
2872
; is initialized only when PNG loading is requested
2873
align 16
2874
@IMPORT:
2875
 
8497 dunkaist 2876
library                           \
2877
        archiver, 'archiver.obj', \
2878
        libio   , 'libio.obj'
7105 dunkaist 2879
 
8497 dunkaist 2880
import  archiver, \
2881
        deflate_unpack2, 'deflate_unpack2',\
2882
        deflateInit2,    'deflateInit2',\
2883
        deflateReset,    'deflateReset',\
2884
        deflate,         'deflate',\
2885
        deflateEnd,      'deflateEnd',\
2886
        calc_crc32,      'calc_crc32'
6807 dunkaist 2887
 
8497 dunkaist 2888
import libio                    , \
2889
        file.size , 'file_size' , \
2890
        file.open , 'file_open' , \
2891
        file.read , 'file_read' , \
2892
        file.close, 'file_close'
7105 dunkaist 2893
 
6807 dunkaist 2894
align 4
2895
; mutex for unpacker loading
8497 dunkaist 2896
deflate_loader_mutex    dd  0
6807 dunkaist 2897
 
2898
; default palette for GIF - b&w
2899
gif_default_palette:
8497 dunkaist 2900
    db  0, 0, 0
2901
    db  0xFF, 0xFF, 0xFF
6807 dunkaist 2902
 
2903
; uninitialized data - global constant tables
2904
mem.alloc   dd ?
2905
mem.free    dd ?
2906
mem.realloc dd ?
2907
dll.load    dd ?
2908
 
2909
; data for YCbCr -> RGB translation
8497 dunkaist 2910
color_table_1       rd  256
2911
color_table_2       rd  256
2912
color_table_3       rd  256
2913
color_table_4       rd  256