Subversion Repositories Kolibri OS

Rev

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

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