Subversion Repositories Kolibri OS

Rev

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