Subversion Repositories Kolibri OS

Rev

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

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