Subversion Repositories Kolibri OS

Rev

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

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