Subversion Repositories Kolibri OS

Rev

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

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