Subversion Repositories Kolibri OS

Rev

Rev 2392 | Rev 2691 | 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
887
    @@: mov eax, [esi]
888
    xchg    eax, [edi]
889
    mov [esi], eax
890
    add esi, 4
891
    add edi, 4
892
    sub ecx, 1
893
    jnz @b
894
    pop ecx
895
    and ecx, 3
896
    jz  .cont_line_vert
999 diamond 897
    @@:
1569 dunkaist 898
    mov al, [esi]
899
    xchg    al, [edi]
900
    mov [esi], al
901
    add esi, 1
902
    add edi, 1
903
    dec ecx
904
    jnz @b
999 diamond 905
    .cont_line_vert:
717 mikedld 906
 
1569 dunkaist 907
    pop ecx
908
    mov eax, [scanline_len]
909
    shl eax, 1
910
    sub edi, eax
911
    dec ecx
912
    jnz .next_line_vert
717 mikedld 913
 
914
  .dont_flip_vert:
915
 
1569 dunkaist 916
    test    [_flip_kind], FLIP_HORIZONTAL
917
    jz  .exit
717 mikedld 918
 
1569 dunkaist 919
    mov ecx, [ebx + Image.Height]
920
    mov eax, [ebx + Image.Type]
921
    mov esi, [ebx + Image.Data]
922
    mov edi, [scanline_len]
923
    add edi, esi
924
    jmp dword [.handlers_horz + (eax-1)*4]
717 mikedld 925
 
1079 diamond 926
.bpp32_horz:
1569 dunkaist 927
    sub edi, 4
999 diamond 928
 
783 mikedld 929
  .next_line_horz:
1569 dunkaist 930
    push    ecx esi edi
783 mikedld 931
 
1569 dunkaist 932
    mov ecx, [scanline_len]
933
    shr ecx, 3
934
    @@: mov eax, [esi]
935
    xchg    eax, [edi]
936
    mov [esi], eax
937
    add esi, 4
938
    add edi, -4
939
    sub ecx, 1
940
    jnz @b
783 mikedld 941
 
1569 dunkaist 942
    pop edi esi ecx
943
    add esi, [scanline_len]
944
    add edi, [scanline_len]
945
    dec ecx
946
    jnz .next_line_horz
947
    jmp .exit
783 mikedld 948
 
1079 diamond 949
.bpp1x_horz:
1569 dunkaist 950
    sub edi, 2
1079 diamond 951
  .next_line_horz1x:
1569 dunkaist 952
    push    ecx esi edi
1079 diamond 953
 
1569 dunkaist 954
    mov ecx, [ebx + Image.Width]
955
    @@: mov ax, [esi]
956
    mov dx, [edi]
957
    mov [edi], ax
958
    mov [esi], dx
959
    add esi, 2
960
    sub edi, 2
961
    sub ecx, 2
962
    ja  @b
1079 diamond 963
 
1569 dunkaist 964
    pop edi esi ecx
965
    add esi, [scanline_len]
966
    add edi, [scanline_len]
967
    dec ecx
968
    jnz .next_line_horz1x
969
    jmp .exit
1079 diamond 970
 
971
.bpp8_horz:
1569 dunkaist 972
    dec edi
999 diamond 973
  .next_line_horz8:
1569 dunkaist 974
    push    ecx esi edi
999 diamond 975
 
1569 dunkaist 976
    mov ecx, [scanline_len]
977
    shr ecx, 1
978
    @@: mov al, [esi]
979
    mov dl, [edi]
980
    mov [edi], al
981
    mov [esi], dl
982
    add esi, 1
983
    sub edi, 1
984
    sub ecx, 1
985
    jnz @b
999 diamond 986
 
1569 dunkaist 987
    pop edi esi ecx
988
    add esi, [scanline_len]
989
    add edi, [scanline_len]
990
    dec ecx
991
    jnz .next_line_horz8
992
    jmp .exit
999 diamond 993
 
1079 diamond 994
.bpp24_horz:
1569 dunkaist 995
    sub edi, 3
1079 diamond 996
  .next_line_horz24:
1569 dunkaist 997
    push    ecx esi edi
999 diamond 998
 
1569 dunkaist 999
    mov ecx, [ebx + Image.Width]
999 diamond 1000
    @@:
1569 dunkaist 1001
    mov al, [esi]
1002
    mov dl, [edi]
1003
    mov [edi], al
1004
    mov [esi], dl
1005
    mov al, [esi+1]
1006
    mov dl, [edi+1]
1007
    mov [edi+1], al
1008
    mov [esi+1], dl
1009
    mov al, [esi+2]
1010
    mov dl, [edi+2]
1011
    mov [edi+2], al
1012
    mov [esi+2], dl
1013
    add esi, 3
1014
    sub edi, 3
1015
    sub ecx, 2
1016
    ja  @b
999 diamond 1017
 
1569 dunkaist 1018
    pop edi esi ecx
1019
    add esi, [scanline_len]
1020
    add edi, [scanline_len]
1021
    dec ecx
1022
    jnz .next_line_horz24
1593 dunkaist 1023
    jmp .exit
999 diamond 1024
 
1593 dunkaist 1025
.bpp1_horz:
1026
    push eax edx
1027
    mov edi, [scanline_len]
1028
    mov edx, [ebx+Image.Width]
1029
    and edx,  0x07
1030
    neg dl
1031
    add dl, 8
1032
    and dl, 0x07                                        ; clear if cl=8
1033
.bpp1_horz.begin:
1034
    push ebx ecx edx esi
1035
    mov eax, 7
1036
    add edi, esi
1037
    sub edi, 1
1038
    mov ebx, [ebx+Image.Width]
1039
    shr ebx, 1
1040
.bpp1_horz.flip_line:
1041
    xor ecx, ecx
1042
    bt  [esi], eax
1043
    setc cl
1044
    bt  [edi], edx
1045
     jc .bpp1_horz.one
1046
  .bpp1_horz.zero:
1047
    btr [esi], eax
1048
     jmp @f
1049
  .bpp1_horz.one:
1050
    bts [esi], eax
1051
  @@:
1052
     jecxz .bpp1_horz.reset
1053
  .bpp1_horz.set:
1054
    bts [edi], edx
1055
     jmp @f
1056
  .bpp1_horz.reset:
1057
    btr [edi], edx
1058
  @@:
1059
    inc edx
1060
    and edx, 0x07
1061
     jnz @f
1062
    dec edi
1063
  @@:
1064
    dec eax
1065
     jns @f
1066
    mov eax, 7
1067
    inc esi
1068
  @@:
1069
    dec ebx
1070
     jnz .bpp1_horz.flip_line
1071
 
1072
    pop esi edx ecx ebx
1073
    add esi, [scanline_len]
1074
    mov edi, [scanline_len]
1075
    dec ecx
1076
     jnz .bpp1_horz.begin
1077
    pop edx eax
1078
 
717 mikedld 1079
  .exit:
1569 dunkaist 1080
    xor eax, eax
1081
    inc eax
1082
    pop edi esi ebx
1083
    ret
717 mikedld 1084
 
1085
  .error:
1569 dunkaist 1086
    xor eax, eax
1087
    pop edi esi ebx
1088
    ret
717 mikedld 1089
endp
1090
 
783 mikedld 1091
;;================================================================================================;;
1079 diamond 1092
proc img.flip _img, _flip_kind ;//////////////////////////////////////////////////////////////////;;
783 mikedld 1093
;;------------------------------------------------------------------------------------------------;;
1079 diamond 1094
;? Flip all layers of image                                                                       ;;
783 mikedld 1095
;;------------------------------------------------------------------------------------------------;;
1096
;> _img = pointer to image                                                                        ;;
1079 diamond 1097
;> _flip_kind = one of FLIP_* constants                                                           ;;
1098
;;------------------------------------------------------------------------------------------------;;
1099
;< eax = false / true                                                                             ;;
1100
;;================================================================================================;;
1569 dunkaist 1101
    push    1
1102
    mov ebx, [_img]
1079 diamond 1103
@@:
1569 dunkaist 1104
    mov eax, [ebx + Image.Previous]
1105
    test    eax, eax
1106
    jz  .loop
1107
    mov ebx, eax
1108
    jmp @b
1079 diamond 1109
.loop:
1569 dunkaist 1110
    stdcall img.flip.layer, ebx, [_flip_kind]
1111
    test    eax, eax
1112
    jnz @f
1113
    mov byte [esp], 0
1079 diamond 1114
@@:
1569 dunkaist 1115
    mov ebx, [ebx + Image.Next]
1116
    test    ebx, ebx
1117
    jnz .loop
1118
    pop eax
1119
    ret
1079 diamond 1120
endp
1121
 
1122
;;================================================================================================;;
1123
proc img.rotate.layer _img, _rotate_kind ;////////////////////////////////////////////////////////;;
1124
;;------------------------------------------------------------------------------------------------;;
1125
;? Rotate image layer                                                                             ;;
1126
;;------------------------------------------------------------------------------------------------;;
1127
;> _img = pointer to image                                                                        ;;
783 mikedld 1128
;> _rotate_kind = one of ROTATE_* constants                                                       ;;
1129
;;------------------------------------------------------------------------------------------------;;
1130
;< eax = false / true                                                                             ;;
1131
;;================================================================================================;;
1132
locals
1133
  scanline_len_old    dd ?
1134
  scanline_len_new    dd ?
1135
  scanline_pixels_new dd ?
1569 dunkaist 1136
  line_buffer         dd ?
1137
  pixels_ptr          dd ?
783 mikedld 1138
endl
717 mikedld 1139
 
1569 dunkaist 1140
    mov [line_buffer], 0
783 mikedld 1141
 
1569 dunkaist 1142
    push    ebx esi edi
1143
    mov ebx, [_img]
1144
    stdcall img._.validate, ebx
1145
    or  eax, eax
1146
    jnz .error
783 mikedld 1147
 
1569 dunkaist 1148
    cmp [_rotate_kind], ROTATE_90_CCW
1149
    je  .rotate_ccw_low
1150
    cmp [_rotate_kind], ROTATE_90_CW
1151
    je  .rotate_cw_low
1152
    cmp [_rotate_kind], ROTATE_180
1153
    je  .flip
1154
    jmp .exit
783 mikedld 1155
 
1156
  .rotate_ccw_low:
1569 dunkaist 1157
    mov eax, [ebx + Image.Height]
1158
    mov [scanline_pixels_new], eax
1159
    call    img._.get_scanline_len
1160
    mov [scanline_len_new], eax
783 mikedld 1161
 
1569 dunkaist 1162
    invoke  mem.alloc, eax
1163
    or  eax, eax
1164
    jz  .error
1165
    mov [line_buffer], eax
783 mikedld 1166
 
1569 dunkaist 1167
    mov eax, [ebx + Image.Width]
1168
    mov ecx, eax
1169
    call    img._.get_scanline_len
1170
    mov [scanline_len_old], eax
783 mikedld 1171
 
1569 dunkaist 1172
    mov eax, [scanline_len_new]
1173
    imul    eax, ecx
1174
    add eax, [ebx + Image.Data]
1175
    mov [pixels_ptr], eax
783 mikedld 1176
 
1593 dunkaist 1177
    cmp [ebx + Image.Type], Image.bpp1
1178
    jz  .rotate_ccw1
1569 dunkaist 1179
    cmp [ebx + Image.Type], Image.bpp8
1180
    jz  .rotate_ccw8
1181
    cmp [ebx + Image.Type], Image.bpp24
1182
    jz  .rotate_ccw24
1183
    cmp [ebx + Image.Type], Image.bpp32
1184
    jz  .rotate_ccw32
999 diamond 1185
 
1079 diamond 1186
  .next_column_ccw_low1x:
1569 dunkaist 1187
    dec ecx
1188
    js  .exchange_dims
1189
    push    ecx
1079 diamond 1190
 
1569 dunkaist 1191
    mov edx, [scanline_len_old]
1192
    add [scanline_len_old], -2
1079 diamond 1193
 
1569 dunkaist 1194
    mov ecx, [scanline_pixels_new]
1195
    mov esi, [ebx + Image.Data]
1196
    mov edi, [line_buffer]
1197
    @@: mov ax, [esi]
1198
    mov [edi], ax
1199
    add esi, edx
1200
    add edi, 2
1201
    sub ecx, 1
1202
    jnz @b
1079 diamond 1203
 
1569 dunkaist 1204
    mov eax, [scanline_pixels_new]
1205
    mov edi, [ebx + Image.Data]
1206
    lea esi, [edi + 2]
1207
    mov edx, [scanline_len_old]
1208
    @@: mov ecx, edx
1209
    shr ecx, 2
1210
    rep movsd
1211
    mov ecx, edx
1212
    and ecx, 3
1213
    rep movsb
1214
    add esi, 1
1215
    sub eax, 1
1216
    jnz @b
1079 diamond 1217
 
1569 dunkaist 1218
    mov eax, [scanline_len_new]
1219
    sub [pixels_ptr], eax
1220
    mov ecx, [scanline_pixels_new]
1221
    mov esi, [line_buffer]
1222
    mov edi, [pixels_ptr]
1223
    mov edx, ecx
1224
    shr ecx, 2
1225
    rep movsd
1226
    mov ecx, edx
1227
    and ecx, 3
1228
    rep movsb
1079 diamond 1229
 
1569 dunkaist 1230
    pop ecx
1231
    jmp .next_column_ccw_low1x
1079 diamond 1232
 
1233
.rotate_ccw32:
783 mikedld 1234
  .next_column_ccw_low:
1569 dunkaist 1235
    dec ecx
1236
    js  .exchange_dims
1237
    push    ecx
783 mikedld 1238
 
1569 dunkaist 1239
    mov edx, [scanline_len_old]
1240
    add [scanline_len_old], -4
783 mikedld 1241
 
1569 dunkaist 1242
    mov ecx, [scanline_pixels_new]
1243
    mov esi, [ebx + Image.Data]
1244
    mov edi, [line_buffer]
1245
    @@: mov eax, [esi]
1246
    stosd
1247
    add esi, edx
1248
    dec ecx
1249
    jnz @b
783 mikedld 1250
 
1569 dunkaist 1251
    mov eax, [scanline_pixels_new]
1252
    mov edi, [ebx + Image.Data]
1253
    lea esi, [edi + 4]
1254
    mov edx, [scanline_len_old]
1255
    shr edx, 2
1256
    @@: mov ecx, edx
1257
    rep movsd
1258
    add esi, 4
1259
    dec eax
1260
    jnz @b
783 mikedld 1261
 
1569 dunkaist 1262
    mov eax, [scanline_len_new]
1263
    sub [pixels_ptr], eax
1264
    mov ecx, [scanline_pixels_new]
1265
    mov esi, [line_buffer]
1266
    mov edi, [pixels_ptr]
1267
    rep movsd
783 mikedld 1268
 
1569 dunkaist 1269
    pop ecx
1270
    jmp .next_column_ccw_low
783 mikedld 1271
 
999 diamond 1272
.rotate_ccw8:
1273
  .next_column_ccw_low8:
1569 dunkaist 1274
    dec ecx
1275
    js  .exchange_dims
1276
    push    ecx
999 diamond 1277
 
1569 dunkaist 1278
    mov edx, [scanline_len_old]
1279
    add [scanline_len_old], -1
999 diamond 1280
 
1569 dunkaist 1281
    mov ecx, [scanline_pixels_new]
1282
    mov esi, [ebx + Image.Data]
1283
    mov edi, [line_buffer]
1284
    @@: mov al, [esi]
1285
    mov [edi], al
1286
    add esi, edx
1287
    add edi, 1
1288
    sub ecx, 1
1289
    jnz @b
999 diamond 1290
 
1569 dunkaist 1291
    mov eax, [scanline_pixels_new]
1292
    mov edi, [ebx + Image.Data]
1293
    lea esi, [edi + 1]
1294
    mov edx, [scanline_len_old]
1295
    @@: mov ecx, edx
1296
    shr ecx, 2
1297
    rep movsd
1298
    mov ecx, edx
1299
    and ecx, 3
1300
    rep movsb
1301
    add esi, 1
1302
    sub eax, 1
1303
    jnz @b
999 diamond 1304
 
1569 dunkaist 1305
    mov eax, [scanline_len_new]
1306
    sub [pixels_ptr], eax
1307
    mov ecx, [scanline_pixels_new]
1308
    mov esi, [line_buffer]
1309
    mov edi, [pixels_ptr]
1310
    mov edx, ecx
1311
    shr ecx, 2
1312
    rep movsd
1313
    mov ecx, edx
1314
    and ecx, 3
1315
    rep movsb
999 diamond 1316
 
1569 dunkaist 1317
    pop ecx
1318
    jmp .next_column_ccw_low8
999 diamond 1319
 
1320
.rotate_ccw24:
1321
  .next_column_ccw_low24:
1569 dunkaist 1322
    dec ecx
1323
    js  .exchange_dims
1324
    push    ecx
999 diamond 1325
 
1569 dunkaist 1326
    mov edx, [scanline_len_old]
1327
    add [scanline_len_old], -3
999 diamond 1328
 
1569 dunkaist 1329
    mov ecx, [scanline_pixels_new]
1330
    mov esi, [ebx + Image.Data]
1331
    mov edi, [line_buffer]
1332
    @@: mov al, [esi]
1333
    mov [edi], al
1334
    mov al, [esi+1]
1335
    mov [edi+1], al
1336
    mov al, [esi+2]
1337
    mov [edi+2], al
1338
    add esi, edx
1339
    add edi, 3
1340
    sub ecx, 1
1341
    jnz @b
999 diamond 1342
 
1569 dunkaist 1343
    mov eax, [scanline_pixels_new]
1344
    mov edi, [ebx + Image.Data]
1345
    lea esi, [edi + 3]
1346
    mov edx, [scanline_len_old]
1347
    @@: mov ecx, edx
1348
    shr ecx, 2
1349
    rep movsd
1350
    mov ecx, edx
1351
    and ecx, 3
1352
    rep movsb
1353
    add esi, 3
1354
    sub eax, 1
1355
    jnz @b
999 diamond 1356
 
1569 dunkaist 1357
    mov eax, [scanline_len_new]
1358
    sub [pixels_ptr], eax
1359
    mov ecx, eax
1360
    mov esi, [line_buffer]
1361
    mov edi, [pixels_ptr]
1362
    shr ecx, 2
1363
    rep movsd
1364
    mov ecx, eax
1365
    and ecx, 3
1366
    rep movsb
999 diamond 1367
 
1569 dunkaist 1368
    pop ecx
1369
    jmp .next_column_ccw_low24
999 diamond 1370
 
1593 dunkaist 1371
.rotate_ccw1:
1372
    push ecx edx
1373
 
1374
    mov eax, [ebx+Image.Height]
1375
    add eax, 7
1376
    shr eax, 3
1377
    mul word[ebx+Image.Width]
1378
    shl eax, 16
1379
    shrd eax, edx, 16
1380
    push eax                                            ; save new data size
1381
 
1382
    invoke  mem.alloc, eax
1383
    or  eax, eax
1384
    jz  .error
1385
    push eax                                            ; save pointer to new data
1386
 
1387
    mov ecx, [ebx+Image.Width]
1388
    and ecx,  0x07
1389
    neg cl
1390
    add cl, 8
1391
    and cl, 0x07                                        ; clear if cl=8
1392
 
1393
    mov esi, eax
1394
    mov edi, [ebx+Image.Data]
1395
    mov eax, 7
1396
    mov edx, [scanline_len_old]
1397
    dec edx
1398
    add edi, edx
1399
 
1400
  .rotate_ccw1.begin:
1401
    bt  [edi], ecx
1402
     jc .rotate_ccw1.one
1403
  .rotate_ccw1.zero:
1404
    btr [esi], eax
1405
     jmp @f
1406
  .rotate_ccw1.one:
1407
    bts [esi], eax
1408
  @@:
1409
    add edi, [scanline_len_old]
1410
    dec [scanline_pixels_new]
1411
     jz .rotate_ccw1.end_of_line
1412
    dec eax
1413
     jns .rotate_ccw1.begin
1414
    mov eax, 7
1415
    inc esi
1416
     jmp .rotate_ccw1.begin
1417
 
1418
  .rotate_ccw1.end_of_line:
1419
    inc esi
1420
    mov eax, 7
1421
    mov edi, [ebx+Image.Height]
1422
    mov [scanline_pixels_new],  edi
1423
    inc ecx
1424
    and cl, 0x07
1425
     jz @f
1426
    mov edi, [ebx+Image.Data]
1427
    add edi, edx
1428
     jmp .rotate_ccw1.begin
1429
  @@:
1430
    dec edx
1431
     js .rotate_ccw1.quit
1432
    mov edi, [ebx+Image.Data]
1433
    add edi, edx
1434
     jmp .rotate_ccw1.begin
1435
 
1436
  .rotate_ccw1.quit:
1437
    pop eax                                             ; get pointer to new data
1438
    mov esi, eax
1439
    mov edi, [ebx + Image.Data]
1440
    pop ecx                                             ; get new data size
1441
    rep movsb
1442
 
1443
    invoke  mem.free, eax
1444
 
1445
    pop edx ecx
1446
     jmp .exchange_dims
1447
 
783 mikedld 1448
  .rotate_cw_low:
1569 dunkaist 1449
    mov eax, [ebx + Image.Height]
1450
    mov [scanline_pixels_new], eax
1451
    call    img._.get_scanline_len
1452
    mov [scanline_len_new], eax
783 mikedld 1453
 
1569 dunkaist 1454
    invoke  mem.alloc, eax
1455
    or  eax, eax
1456
    jz  .error
1457
    mov [line_buffer], eax
783 mikedld 1458
 
1569 dunkaist 1459
    mov eax, [ebx + Image.Width]
1460
    mov ecx, eax
1461
    call    img._.get_scanline_len
1462
    mov [scanline_len_old], eax
783 mikedld 1463
 
1569 dunkaist 1464
    mov eax, [scanline_len_new]
1465
    imul    eax, ecx
1466
    add eax, [ebx + Image.Data]
1467
    mov [pixels_ptr], eax
783 mikedld 1468
 
1593 dunkaist 1469
    cmp [ebx + Image.Type], Image.bpp1
1470
    jz  .rotate_cw1
1569 dunkaist 1471
    cmp [ebx + Image.Type], Image.bpp8
1472
    jz  .rotate_cw8
1473
    cmp [ebx + Image.Type], Image.bpp24
1474
    jz  .rotate_cw24
1475
    cmp [ebx + Image.Type], Image.bpp32
1476
    jz  .rotate_cw32
999 diamond 1477
 
1079 diamond 1478
  .next_column_cw_low1x:
1569 dunkaist 1479
    dec ecx
1480
    js  .exchange_dims
1481
    push    ecx
1079 diamond 1482
 
1569 dunkaist 1483
    mov edx, [scanline_len_old]
1484
    add [scanline_len_old], -2
1079 diamond 1485
 
1569 dunkaist 1486
    mov ecx, [scanline_pixels_new]
1487
    mov esi, [pixels_ptr]
1488
    add esi, -2
1489
    mov edi, [line_buffer]
1490
    @@: mov ax, [esi]
1491
    mov [edi], ax
1492
    sub esi, edx
1493
    add edi, 2
1494
    sub ecx, 1
1495
    jnz @b
1079 diamond 1496
 
1569 dunkaist 1497
    mov eax, [scanline_pixels_new]
1498
    dec eax
1499
    mov edi, [ebx + Image.Data]
1500
    add edi, [scanline_len_old]
1501
    lea esi, [edi + 2]
1502
    mov edx, [scanline_len_old]
1503
    @@: mov ecx, edx
1504
    shr ecx, 2
1505
    rep movsd
1506
    mov ecx, edx
1507
    and ecx, 3
1508
    rep movsb
1509
    add esi, 3
1510
    sub eax, 1
1511
    jnz @b
1079 diamond 1512
 
1569 dunkaist 1513
    mov eax, [scanline_len_new]
1514
    sub [pixels_ptr], eax
1515
    mov ecx, eax
1516
    mov esi, [line_buffer]
1517
    mov edi, [pixels_ptr]
1518
    shr ecx, 2
1519
    rep movsd
1520
    mov ecx, eax
1521
    and ecx, 3
1522
    rep movsb
1079 diamond 1523
 
1569 dunkaist 1524
    pop ecx
1525
    jmp .next_column_cw_low1x
1079 diamond 1526
 
1527
.rotate_cw32:
783 mikedld 1528
  .next_column_cw_low:
1569 dunkaist 1529
    dec ecx
1530
    js  .exchange_dims
1531
    push    ecx
783 mikedld 1532
 
1569 dunkaist 1533
    mov edx, [scanline_len_old]
1534
    add [scanline_len_old], -4
783 mikedld 1535
 
1569 dunkaist 1536
    mov ecx, [scanline_pixels_new]
1537
    mov esi, [pixels_ptr]
1538
    add esi, -4
1539
    mov edi, [line_buffer]
1540
    @@: mov eax, [esi]
1541
    stosd
1542
    sub esi, edx
1543
    dec ecx
1544
    jnz @b
783 mikedld 1545
 
1569 dunkaist 1546
    mov eax, [scanline_pixels_new]
1547
    dec eax
1548
    mov edi, [ebx + Image.Data]
1549
    add edi, [scanline_len_old]
1550
    lea esi, [edi + 4]
1551
    mov edx, [scanline_len_old]
1552
    shr edx, 2
1553
    @@: mov ecx, edx
1554
    rep movsd
1555
    add esi, 4
1556
    dec eax
1557
    jnz @b
783 mikedld 1558
 
1569 dunkaist 1559
    mov eax, [scanline_len_new]
1560
    sub [pixels_ptr], eax
1561
    mov ecx, [scanline_pixels_new]
1562
    mov esi, [line_buffer]
1563
    mov edi, [pixels_ptr]
1564
    rep movsd
783 mikedld 1565
 
1569 dunkaist 1566
    pop ecx
1567
    jmp .next_column_cw_low
783 mikedld 1568
 
999 diamond 1569
.rotate_cw8:
1570
  .next_column_cw_low8:
1569 dunkaist 1571
    dec ecx
1572
    js  .exchange_dims
1573
    push    ecx
999 diamond 1574
 
1569 dunkaist 1575
    mov edx, [scanline_len_old]
1576
    add [scanline_len_old], -1
999 diamond 1577
 
1569 dunkaist 1578
    mov ecx, [scanline_pixels_new]
1579
    mov esi, [pixels_ptr]
1580
    add esi, -1
1581
    mov edi, [line_buffer]
1582
    @@: mov al, [esi]
1583
    mov [edi], al
1584
    sub esi, edx
1585
    add edi, 1
1586
    sub ecx, 1
1587
    jnz @b
999 diamond 1588
 
1569 dunkaist 1589
    mov eax, [scanline_pixels_new]
1590
    dec eax
1591
    mov edi, [ebx + Image.Data]
1592
    add edi, [scanline_len_old]
1593
    lea esi, [edi + 1]
1594
    mov edx, [scanline_len_old]
1595
    @@: mov ecx, edx
1596
    shr ecx, 2
1597
    rep movsd
1598
    mov ecx, edx
1599
    and ecx, 3
1600
    rep movsb
1601
    add esi, 1
1602
    sub eax, 1
1603
    jnz @b
999 diamond 1604
 
1569 dunkaist 1605
    mov eax, [scanline_len_new]
1606
    sub [pixels_ptr], eax
1607
    mov ecx, eax
1608
    mov esi, [line_buffer]
1609
    mov edi, [pixels_ptr]
1610
    shr ecx, 2
1611
    rep movsd
1612
    mov ecx, eax
1613
    and ecx, 3
1614
    rep movsb
999 diamond 1615
 
1569 dunkaist 1616
    pop ecx
1617
    jmp .next_column_cw_low8
999 diamond 1618
 
1619
.rotate_cw24:
1620
  .next_column_cw_low24:
1569 dunkaist 1621
    dec ecx
1622
    js  .exchange_dims
1623
    push    ecx
999 diamond 1624
 
1569 dunkaist 1625
    mov edx, [scanline_len_old]
1626
    add [scanline_len_old], -3
999 diamond 1627
 
1569 dunkaist 1628
    mov ecx, [scanline_pixels_new]
1629
    mov esi, [pixels_ptr]
1630
    add esi, -3
1631
    mov edi, [line_buffer]
1632
    @@: mov al, [esi]
1633
    mov [edi], al
1634
    mov al, [esi+1]
1635
    mov [edi+1], al
1636
    mov al, [esi+2]
1637
    mov [edi+2], al
1638
    sub esi, edx
1639
    add edi, 3
1640
    sub ecx, 1
1641
    jnz @b
999 diamond 1642
 
1569 dunkaist 1643
    mov eax, [scanline_pixels_new]
1644
    dec eax
1645
    mov edi, [ebx + Image.Data]
1646
    add edi, [scanline_len_old]
1647
    lea esi, [edi + 3]
1648
    mov edx, [scanline_len_old]
1649
    @@: mov ecx, edx
1650
    shr ecx, 2
1651
    rep movsd
1652
    mov ecx, edx
1653
    and ecx, 3
1654
    rep movsb
1655
    add esi, 3
1656
    sub eax, 1
1657
    jnz @b
999 diamond 1658
 
1569 dunkaist 1659
    mov eax, [scanline_len_new]
1660
    sub [pixels_ptr], eax
1661
    mov ecx, eax
1662
    mov esi, [line_buffer]
1663
    mov edi, [pixels_ptr]
1664
    shr ecx, 2
1665
    rep movsd
1666
    mov ecx, eax
1667
    and ecx, 3
1668
    rep movsb
999 diamond 1669
 
1569 dunkaist 1670
    pop ecx
1671
    jmp .next_column_cw_low24
999 diamond 1672
 
1593 dunkaist 1673
.rotate_cw1:
1674
    push ecx edx
1675
 
1676
    mov eax, [ebx+Image.Height]
1677
    add eax, 7
1678
    shr eax, 3
1679
    mul word[ebx+Image.Width]
1680
    shl eax, 16
1681
    shrd eax, edx, 16
1682
 
1683
    push eax                                            ; save new data size
1684
 
1685
    invoke  mem.alloc, eax
1686
    or  eax, eax
1687
    jz  .error
1688
    push eax                                            ; save pointer to new data
1689
 
1690
    mov ecx, 7
1691
 
1692
    mov edx, [ebx+Image.Width]
1693
    mov [pixels_ptr],   edx                             ; we don't use pixels_ptr as it do other procedures, we save there [ebx+Image.Width]
1694
    mov esi, eax
1695
    mov edi, [ebx+Image.Data]
1696
    mov eax, [ebx+Image.Height]
1697
    dec eax
1698
    mul [scanline_len_old]
1699
    add edi, eax
1700
    mov eax, 7
1701
    mov edx, 0
1702
 
1703
  .rotate_cw1.begin:
1704
    bt  [edi], ecx
1705
     jc .rotate_cw1.one
1706
  .rotate_cw1.zero:
1707
    btr [esi], eax
1708
     jmp @f
1709
  .rotate_cw1.one:
1710
    bts [esi], eax
1711
  @@:
1712
    sub edi, [scanline_len_old]
1713
    dec [scanline_pixels_new]
1714
     jz .rotate_cw1.end_of_line
1715
    dec eax
1716
     jns .rotate_cw1.begin
1717
    mov eax, 7
1718
    inc esi
1719
     jmp .rotate_cw1.begin
1720
 
1721
  .rotate_cw1.end_of_line:
1722
    dec [pixels_ptr]
1723
     jz .rotate_cw1.quit
1724
    inc esi
1725
    mov eax, [ebx+Image.Height]
1726
    mov [scanline_pixels_new],   eax
1727
    mov eax, 7
1728
    dec ecx
1729
     js @f
1730
    mov edi, [ebx+Image.Height]
1731
    dec edi
1732
    imul edi, [scanline_len_old]
1733
    add edi, [ebx+Image.Data]
1734
    add edi, edx
1735
     jmp .rotate_cw1.begin
1736
  @@:
1737
    mov ecx, 7
1738
    inc edx
1739
    cmp edx, [scanline_len_old]
1740
     je .rotate_cw1.quit
1741
    mov edi, [ebx+Image.Height]
1742
    dec edi
1743
    imul edi, [scanline_len_old]
1744
    add edi, [ebx+Image.Data]
1745
    add edi, edx
1746
     jmp .rotate_cw1.begin
1747
 
1748
  .rotate_cw1.quit:
1749
    pop eax                                             ; get pointer to new data
1750
    mov esi, eax
1751
    mov edi, [ebx + Image.Data]
1752
    pop ecx                                             ; get new data size
1753
    rep movsb
1754
 
1755
    invoke  mem.free, eax
1756
 
1757
    pop edx ecx
1758
     jmp .exchange_dims
1759
 
783 mikedld 1760
  .flip:
1569 dunkaist 1761
    jmp .exit
783 mikedld 1762
 
1763
  .exchange_dims:
1569 dunkaist 1764
    push    [ebx + Image.Width] [ebx + Image.Height]
1765
    pop [ebx + Image.Width] [ebx + Image.Height]
783 mikedld 1766
 
1767
  .exit:
1569 dunkaist 1768
    invoke  mem.free, [line_buffer]
1769
    xor eax, eax
1770
    inc eax
1771
    pop edi esi ebx
1772
    ret
783 mikedld 1773
 
1774
  .error:
1569 dunkaist 1775
    invoke  mem.free, [line_buffer]
1776
    xor eax, eax
1777
    pop edi esi ebx
1778
    ret
783 mikedld 1779
endp
1780
 
1079 diamond 1781
;;================================================================================================;;
1782
proc img.rotate _img, _rotate_kind ;//////////////////////////////////////////////////////////////;;
1783
;;------------------------------------------------------------------------------------------------;;
1784
;? Rotate all layers of image                                                                     ;;
1785
;;------------------------------------------------------------------------------------------------;;
1786
;> _img = pointer to image                                                                        ;;
1787
;> _rotate_kind = one of ROTATE_* constants                                                       ;;
1788
;;------------------------------------------------------------------------------------------------;;
1789
;< eax = false / true                                                                             ;;
1790
;;================================================================================================;;
1569 dunkaist 1791
    push    1
1792
    mov ebx, [_img]
1079 diamond 1793
@@:
1569 dunkaist 1794
    mov eax, [ebx + Image.Previous]
1795
    test    eax, eax
1796
    jz  .loop
1797
    mov ebx, eax
1798
    jmp @b
1079 diamond 1799
.loop:
1569 dunkaist 1800
    stdcall img.rotate.layer, ebx, [_rotate_kind]
1801
    test    eax, eax
1802
    jnz @f
1803
    mov byte [esp], 0
1079 diamond 1804
@@:
1569 dunkaist 1805
    mov ebx, [ebx + Image.Next]
1806
    test    ebx, ebx
1807
    jnz .loop
1808
    pop eax
1809
    ret
1079 diamond 1810
endp
783 mikedld 1811
 
717 mikedld 1812
;;================================================================================================;;
1079 diamond 1813
proc img.draw _img, _x, _y, _width, _height, _xpos, _ypos ;///////////////////////////////////////;;
1814
;;------------------------------------------------------------------------------------------------;;
1815
;? Draw image in the window                                                                       ;;
1816
;;------------------------------------------------------------------------------------------------;;
1817
;> _img = pointer to image                                                                        ;;
1818
;>_x = x-coordinate in the window                                                                 ;;
1819
;>_y = y-coordinate in the window                                                                 ;;
1820
;>_width = maximum width to draw                                                                  ;;
1821
;>_height = maximum height to draw                                                                ;;
1822
;>_xpos = offset in image by x-axis                                                               ;;
1823
;>_ypos = offset in image by y-axis                                                               ;;
1824
;;------------------------------------------------------------------------------------------------;;
1825
;< no return value                                                                                ;;
1826
;;================================================================================================;;
1569 dunkaist 1827
    push    ebx esi edi
1828
    mov ebx, [_img]
1829
    stdcall img._.validate, ebx
1830
    test    eax, eax
1831
    jnz .done
1832
    mov ecx, [ebx + Image.Width]
1833
    sub ecx, [_xpos]
1834
    jbe .done
1835
    cmp ecx, [_width]
1836
    jb  @f
1837
    mov ecx, [_width]
1079 diamond 1838
@@:
1569 dunkaist 1839
    mov edx, [ebx + Image.Height]
1840
    sub edx, [_ypos]
1841
    jbe .done
1842
    cmp edx, [_height]
1843
    jb  @f
1844
    mov edx, [_height]
1079 diamond 1845
@@:
1569 dunkaist 1846
    mov eax, [ebx + Image.Width]
1847
    sub eax, ecx
1848
    call    img._.get_scanline_len
1849
    shl ecx, 16
1850
    add ecx, edx
1851
    push    eax
1852
    mov eax, [ebx + Image.Width]
1853
    imul    eax, [_ypos]
1854
    add eax, [_xpos]
1855
    call    img._.get_scanline_len
1856
    add eax, [ebx + Image.Data]
1857
    mov edx, [_x - 2]
1858
    mov dx, word [_y]
1859
    mov esi, [ebx + Image.Type]
1860
    mov esi, [type2bpp + (esi-1)*4]
1861
    mov edi, [ebx + Image.Palette]
1862
    xchg    eax, ebx
1863
    pop eax
1864
    push    ebp
1865
    push    65
1866
    pop ebp
1867
    xchg    eax, ebp
1868
    int 40h
1869
    pop ebp
1079 diamond 1870
.done:
1569 dunkaist 1871
    pop edi esi ebx
1872
    ret
1079 diamond 1873
endp
1874
 
2684 dunkaist 1875
 
1876
align 4
1877
img.formats_table:
1878
  .bmp  dd LIBIMG_FORMAT_ID_BMP,  img.is.bmp,  img.decode.bmp,     img.encode.bmp, 0
1879
  .ico  dd LIBIMG_FORMAT_ID_ICO,  img.is.ico,  img.decode.ico_cur, img.encode.ico, 0
1880
  .cur  dd LIBIMG_FORMAT_ID_CUR,  img.is.cur,  img.decode.ico_cur, img.encode.cur, 0
1881
  .gif  dd LIBIMG_FORMAT_ID_GIF,  img.is.gif,  img.decode.gif,     img.encode.gif, 0
1882
  .png  dd LIBIMG_FORMAT_ID_PNG,  img.is.png,  img.decode.png,     img.encode.png, 0
1883
  .jpg  dd LIBIMG_FORMAT_ID_JPEG, img.is.jpg,  img.decode.jpg,     img.encode.jpg, 0
1884
  .tga  dd LIBIMG_FORMAT_ID_TGA,  img.is.tga,  img.decode.tga,     img.encode.tga, 0
1885
  .pcx  dd LIBIMG_FORMAT_ID_PCX,  img.is.pcx,  img.decode.pcx,     img.encode.pcx, 0
1886
  .xcf  dd LIBIMG_FORMAT_ID_XCF,  img.is.xcf,  img.decode.xcf,     img.encode.xcf, 0
1887
  .tiff dd LIBIMG_FORMAT_ID_TIFF, img.is.tiff, img.decode.tiff,    img.encode.tiff,0
1888
  .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)
1889
  .wbmp dd LIBIMG_FORMAT_ID_WBMP, img.is.wbmp, img.decode.wbmp,    img.encode.wbmp,0
1890
  .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
1891
        dd 0
1892
 
1079 diamond 1893
;;================================================================================================;;
717 mikedld 1894
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1895
;;================================================================================================;;
1896
;! Below are private procs you should never call directly from your code                          ;;
1897
;;================================================================================================;;
1898
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1899
;;================================================================================================;;
1900
 
1901
 
1902
;;================================================================================================;;
1903
proc img._.validate, _img ;///////////////////////////////////////////////////////////////////////;;
1904
;;------------------------------------------------------------------------------------------------;;
1905
;? --- TBD ---                                                                                    ;;
1906
;;------------------------------------------------------------------------------------------------;;
1907
;> --- TBD ---                                                                                    ;;
1908
;;------------------------------------------------------------------------------------------------;;
1909
;< --- TBD ---                                                                                    ;;
1910
;;================================================================================================;;
1569 dunkaist 1911
    xor eax, eax
1912
    ret
717 mikedld 1913
endp
1914
 
1915
;;================================================================================================;;
1916
proc img._.new ;//////////////////////////////////////////////////////////////////////////////////;;
1917
;;------------------------------------------------------------------------------------------------;;
1918
;? --- TBD ---                                                                                    ;;
1919
;;------------------------------------------------------------------------------------------------;;
1920
;> --- TBD ---                                                                                    ;;
1921
;;------------------------------------------------------------------------------------------------;;
1922
;< eax = 0 / pointer to image                                                                     ;;
1923
;;================================================================================================;;
1569 dunkaist 1924
    invoke  mem.alloc, sizeof.Image
1925
    test    eax, eax
1926
    jz  @f
1927
    push    ecx
1928
    xor ecx, ecx
1929
    mov [eax + Image.Data], ecx
1930
    mov [eax + Image.Type], ecx
1931
    mov [eax + Image.Flags], ecx
1932
    mov [eax + Image.Extended], ecx
1933
    mov [eax + Image.Previous], ecx
1934
    mov [eax + Image.Next], ecx
1935
    pop ecx
999 diamond 1936
@@:
1569 dunkaist 1937
    ret
717 mikedld 1938
endp
1939
 
1940
;;================================================================================================;;
1941
proc img._.delete _img ;//////////////////////////////////////////////////////////////////////////;;
1942
;;------------------------------------------------------------------------------------------------;;
1943
;? --- TBD ---                                                                                    ;;
1944
;;------------------------------------------------------------------------------------------------;;
1945
;> --- TBD ---                                                                                    ;;
1946
;;------------------------------------------------------------------------------------------------;;
1947
;< eax = false / true                                                                             ;;
1948
;;================================================================================================;;
1569 dunkaist 1949
    push    edx
1950
    mov edx, [_img]
1951
    cmp [edx + Image.Data], 0
1952
    je  @f
1953
    invoke  mem.free, [edx + Image.Data]
1954
    @@: cmp [edx + Image.Extended], 0
1955
    je  @f
1956
    invoke  mem.free, [edx + Image.Extended]
1957
    @@: invoke  mem.free, edx
1958
    pop edx
1959
    ret
717 mikedld 1960
endp
1961
 
783 mikedld 1962
;;================================================================================================;;
1963
proc img._.resize_data _img, _width, _height ;////////////////////////////////////////////////////;;
1964
;;------------------------------------------------------------------------------------------------;;
1965
;? --- TBD ---                                                                                    ;;
1966
;;------------------------------------------------------------------------------------------------;;
1967
;> --- TBD ---                                                                                    ;;
1968
;;------------------------------------------------------------------------------------------------;;
1969
;< --- TBD ---                                                                                    ;;
1970
;;================================================================================================;;
1569 dunkaist 1971
    push    ebx esi
1972
    mov ebx, [_img]
1973
    mov eax, [_height]
999 diamond 1974
; our memory is limited, [_width]*[_height] must not overflow
1975
; image with width or height greater than 65535 is most likely bogus
1569 dunkaist 1976
    cmp word [_width+2], 0
1977
    jnz .error
1978
    cmp word [_height+2], 0
1979
    jnz .error
1980
    imul    eax, [_width]
1981
    test    eax, eax
1982
    jz  .error
999 diamond 1983
; do not allow images which require too many memory
1569 dunkaist 1984
    cmp eax, 4000000h
1985
    jae .error
1593 dunkaist 1986
    cmp [ebx + Image.Type], Image.bpp1
1987
    jz  .bpp1
1569 dunkaist 1988
    cmp [ebx + Image.Type], Image.bpp8
1989
    jz  .bpp8
1990
    cmp [ebx + Image.Type], Image.bpp24
1991
    jz  .bpp24
999 diamond 1992
.bpp32:
1569 dunkaist 1993
    shl eax, 2
1994
    jmp @f
999 diamond 1995
.bpp24:
1569 dunkaist 1996
    lea eax, [eax*3]
1997
    jmp @f
999 diamond 1998
.bpp8:
1569 dunkaist 1999
    add eax, 256*4  ; for palette
1593 dunkaist 2000
    jmp @f
2001
.bpp1:
2002
    mov eax, [_width]
2003
    add eax, 7
2004
    shr eax, 3
2005
    mul word[_height]
2006
    shl eax, 16
2007
    mov ax,  dx
2008
    ror eax, 16
2009
 
2010
    push ebx
2011
    mov ebx, eax
2012
 
2013
    mov eax, [_height]
2014
    add eax, 7
2015
    shr eax, 3
2016
    mul word[_width]
2017
    shl eax, 16
2018
    mov ax,  dx
2019
    ror eax, 16
2020
 
2021
    cmp eax, ebx
2022
     jge .bpp1.skip
2023
    mov eax, ebx
2024
  .bpp1.skip:
2025
    pop ebx
2026
 
2027
    add eax, 2*4    ; for palette
999 diamond 2028
@@:
1569 dunkaist 2029
    mov esi, eax
2030
    invoke  mem.realloc, [ebx + Image.Data], eax
2031
    or  eax, eax
2032
    jz  .error
717 mikedld 2033
 
1569 dunkaist 2034
    mov [ebx + Image.Data], eax
2035
    push    [_width]
2036
    pop [ebx + Image.Width]
2037
    push    [_height]
2038
    pop [ebx + Image.Height]
2039
    cmp [ebx + Image.Type], Image.bpp8
1593 dunkaist 2040
    jnz @f
1569 dunkaist 2041
    lea esi, [eax + esi - 256*4]
2042
    mov [ebx + Image.Palette], esi
2043
    jmp .ret
1593 dunkaist 2044
@@:
2045
    cmp [ebx + Image.Type], Image.bpp1
2046
    jnz .ret
2047
    lea esi, [eax + esi - 2*4]
2048
    mov [ebx + Image.Palette], esi
2049
    jmp .ret
783 mikedld 2050
 
2051
  .error:
1569 dunkaist 2052
    xor eax, eax
999 diamond 2053
  .ret:
1569 dunkaist 2054
    pop esi ebx
2055
    ret
783 mikedld 2056
endp
2057
 
999 diamond 2058
;;================================================================================================;;
2059
img._.get_scanline_len: ;/////////////////////////////////////////////////////////////////////////;;
2060
;;------------------------------------------------------------------------------------------------;;
2061
;? --- TBD ---                                                                                    ;;
2062
;;------------------------------------------------------------------------------------------------;;
2063
;> --- TBD ---                                                                                    ;;
2064
;;------------------------------------------------------------------------------------------------;;
2065
;< --- TBD ---                                                                                    ;;
2066
;;================================================================================================;;
1593 dunkaist 2067
    cmp [ebx + Image.Type], Image.bpp1
2068
    jz  .bpp1.1
1569 dunkaist 2069
    cmp [ebx + Image.Type], Image.bpp8
2070
    jz  .bpp8.1
2071
    cmp [ebx + Image.Type], Image.bpp24
2072
    jz  .bpp24.1
2073
    add eax, eax
2074
    cmp [ebx + Image.Type], Image.bpp32
1593 dunkaist 2075
    jnz .quit
1569 dunkaist 2076
    add eax, eax
1593 dunkaist 2077
    jmp .quit
999 diamond 2078
.bpp24.1:
1569 dunkaist 2079
    lea eax, [eax*3]
1593 dunkaist 2080
    jmp .quit
2081
.bpp1.1:
2082
    add eax, 7
2083
    shr eax, 3
999 diamond 2084
.bpp8.1:
1593 dunkaist 2085
.quit:
1569 dunkaist 2086
    ret
783 mikedld 2087
 
999 diamond 2088
 
717 mikedld 2089
;;================================================================================================;;
2090
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
2091
;;================================================================================================;;
2092
;! Below is private data you should never use directly from your code                             ;;
2093
;;================================================================================================;;
2094
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
2095
;;================================================================================================;;
2096
 
1079 diamond 2097
align 4
1593 dunkaist 2098
type2bpp    dd  8, 24, 32, 15, 16, 1
1079 diamond 2099
img._.do_rgb.handlers:
1569 dunkaist 2100
    dd  img._.do_rgb.bpp8
2101
    dd  img._.do_rgb.bpp24
2102
    dd  img._.do_rgb.bpp32
2103
    dd  img._.do_rgb.bpp15.amd  ; can be overwritten in lib_init
2104
    dd  img._.do_rgb.bpp16.amd  ; can be overwritten in lib_init
1593 dunkaist 2105
    dd  img._.do_rgb.bpp1
717 mikedld 2106
 
1079 diamond 2107
img.flip.layer.handlers_horz:
1569 dunkaist 2108
    dd  img.flip.layer.bpp8_horz
2109
    dd  img.flip.layer.bpp24_horz
2110
    dd  img.flip.layer.bpp32_horz
2111
    dd  img.flip.layer.bpp1x_horz
2112
    dd  img.flip.layer.bpp1x_horz
1593 dunkaist 2113
    dd  img.flip.layer.bpp1_horz
1079 diamond 2114
 
717 mikedld 2115
;;================================================================================================;;
2116
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
2117
;;================================================================================================;;
2118
;! Exported functions section                                                                     ;;
2119
;;================================================================================================;;
2120
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
2121
;;================================================================================================;;
2122
 
2123
 
999 diamond 2124
align 4
717 mikedld 2125
@EXPORT:
2126
 
2684 dunkaist 2127
export                                      \
2128
    lib_init         , 'lib_init'         , \
2129
    0x00050007       , 'version'          , \
2130
    img.is_img       , 'img_is_img'       , \
2131
    img.info         , 'img_info'         , \
2132
    img.from_file    , 'img_from_file'    , \
2133
    img.to_file      , 'img_to_file'      , \
2134
    img.from_rgb     , 'img_from_rgb'     , \
2135
    img.to_rgb       , 'img_to_rgb'       , \
2136
    img.to_rgb2      , 'img_to_rgb2'      , \
2137
    img.decode       , 'img_decode'       , \
2138
    img.encode       , 'img_encode'       , \
2139
    img.create       , 'img_create'       , \
2140
    img.destroy      , 'img_destroy'      , \
1569 dunkaist 2141
    img.destroy.layer, 'img_destroy_layer', \
2684 dunkaist 2142
    img.count        , 'img_count'        , \
2143
    img.lock_bits    , 'img_lock_bits'    , \
2144
    img.unlock_bits  , 'img_unlock_bits'  , \
2145
    img.flip         , 'img_flip'         , \
2146
    img.flip.layer   , 'img_flip_layer'   , \
2147
    img.rotate       , 'img_rotate'       , \
2148
    img.rotate.layer , 'img_rotate_layer' , \
2149
    img.draw         , 'img_draw'         , \
2150
    img.formats_table, 'img_formats_table'
999 diamond 2151
 
1014 diamond 2152
; import from deflate unpacker
2153
; is initialized only when PNG loading is requested
2154
align 4
2155
@IMPORT:
2156
 
1102 diamond 2157
library archiver, 'archiver.obj'
1569 dunkaist 2158
import  archiver, \
2159
    deflate_unpack2, 'deflate_unpack2'
1014 diamond 2160
 
1079 diamond 2161
align 4
1014 diamond 2162
; mutex for unpacker loading
1569 dunkaist 2163
deflate_loader_mutex    dd  0
1014 diamond 2164
 
1079 diamond 2165
; default palette for GIF - b&w
2166
gif_default_palette:
1569 dunkaist 2167
    db  0, 0, 0
2168
    db  0xFF, 0xFF, 0xFF
1079 diamond 2169
 
999 diamond 2170
section '.data' data readable writable align 16
2171
; uninitialized data - global constant tables
1079 diamond 2172
mem.alloc   dd ?
2173
mem.free    dd ?
2174
mem.realloc dd ?
2175
dll.load    dd ?
999 diamond 2176
 
2177
; data for YCbCr -> RGB translation
1569 dunkaist 2178
color_table_1       rd  256
2179
color_table_2       rd  256
2180
color_table_3       rd  256
2181
color_table_4       rd  256