Subversion Repositories Kolibri OS

Rev

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

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