Subversion Repositories Kolibri OS

Rev

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