Subversion Repositories Kolibri OS

Rev

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