Subversion Repositories Kolibri OS

Rev

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

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