Subversion Repositories Kolibri OS

Rev

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