Subversion Repositories Kolibri OS

Rev

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

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