Subversion Repositories Kolibri OS

Rev

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