Subversion Repositories Kolibri OS

Rev

Rev 783 | Rev 1001 | 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'
31
 
32
section '.flat' code readable align 16
33
 
34
include 'bmp/bmp.asm'
35
include 'gif/gif.asm'
999 diamond 36
include 'jpeg/jpeg.asm'
717 mikedld 37
 
38
mem.alloc   dd ?
39
mem.free    dd ?
40
mem.realloc dd ?
41
dll.load    dd ?
42
 
43
;;================================================================================================;;
44
proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
45
;;------------------------------------------------------------------------------------------------;;
46
;? Library entry point (called after library load)                                                ;;
47
;;------------------------------------------------------------------------------------------------;;
48
;> eax = pointer to memory allocation routine                                                     ;;
49
;> ebx = pointer to memory freeing routine                                                        ;;
50
;> ecx = pointer to memory reallocation routine                                                   ;;
51
;> edx = pointer to library loading routine                                                       ;;
52
;;------------------------------------------------------------------------------------------------;;
53
;< eax = 1 (fail) / 0 (ok) (library initialization result)                                        ;;
54
;;================================================================================================;;
55
	mov	[mem.alloc], eax
56
	mov	[mem.free], ebx
57
	mov	[mem.realloc], ecx
58
	mov	[dll.load], edx
59
 
999 diamond 60
	call	img.initialize.jpeg
61
 
717 mikedld 62
  .ok:	xor	eax,eax
63
	ret
64
endp
65
 
66
;;================================================================================================;;
67
proc img.is_img _data, _length ;//////////////////////////////////////////////////////////////////;;
68
;;------------------------------------------------------------------------------------------------;;
69
;? --- TBD ---                                                                                    ;;
70
;;------------------------------------------------------------------------------------------------;;
71
;> --- TBD ---                                                                                    ;;
72
;;------------------------------------------------------------------------------------------------;;
73
;< --- TBD ---                                                                                    ;;
74
;;================================================================================================;;
75
	push	ebx
76
	mov	ebx, img._.formats_table
77
    @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
78
	or	eax, eax
79
	jnz	@f
80
	add	ebx, sizeof.FormatsTableEntry
81
	cmp	dword[ebx], 0
82
	jnz	@b
83
	xor	eax, eax
84
    @@: pop	ebx
85
	ret
86
endp
87
 
88
;;================================================================================================;;
89
proc img.info _data, _length ;////////////////////////////////////////////////////////////////////;;
90
;;------------------------------------------------------------------------------------------------;;
91
;? --- TBD ---                                                                                    ;;
92
;;------------------------------------------------------------------------------------------------;;
93
;> --- TBD ---                                                                                    ;;
94
;;------------------------------------------------------------------------------------------------;;
95
;< --- TBD ---                                                                                    ;;
96
;;================================================================================================;;
97
	xor	eax, eax
98
	ret
99
endp
100
 
101
;;================================================================================================;;
102
proc img.from_file _filename ;////////////////////////////////////////////////////////////////////;;
103
;;------------------------------------------------------------------------------------------------;;
104
;? --- TBD ---                                                                                    ;;
105
;;------------------------------------------------------------------------------------------------;;
106
;> --- TBD ---                                                                                    ;;
107
;;------------------------------------------------------------------------------------------------;;
108
;< eax = 0 / pointer to image                                                                     ;;
109
;;================================================================================================;;
110
	xor	eax, eax
111
	ret
112
endp
113
 
114
;;================================================================================================;;
115
proc img.to_file _img, _filename ;////////////////////////////////////////////////////////////////;;
116
;;------------------------------------------------------------------------------------------------;;
117
;? --- TBD ---                                                                                    ;;
118
;;------------------------------------------------------------------------------------------------;;
119
;> --- TBD ---                                                                                    ;;
120
;;------------------------------------------------------------------------------------------------;;
121
;< eax = false / true                                                                             ;;
122
;;================================================================================================;;
123
	xor	eax, eax
124
	ret
125
endp
126
 
127
;;================================================================================================;;
128
proc img.from_rgb _rgb_data ;/////////////////////////////////////////////////////////////////////;;
129
;;------------------------------------------------------------------------------------------------;;
130
;? --- TBD ---                                                                                    ;;
131
;;------------------------------------------------------------------------------------------------;;
132
;> --- TBD ---                                                                                    ;;
133
;;------------------------------------------------------------------------------------------------;;
134
;< eax = 0 / pointer to image                                                                     ;;
135
;;================================================================================================;;
136
	xor	eax, eax
137
	ret
138
endp
139
 
140
;;================================================================================================;;
141
proc img.to_rgb _img ;////////////////////////////////////////////////////////////////////////////;;
142
;;------------------------------------------------------------------------------------------------;;
143
;? --- TBD ---                                                                                    ;;
144
;;------------------------------------------------------------------------------------------------;;
145
;> --- TBD ---                                                                                    ;;
146
;;------------------------------------------------------------------------------------------------;;
147
;< eax = 0 / pointer to rgb_data (array of [rgb] triplets)                                        ;;
148
;;================================================================================================;;
149
	push	esi edi
150
	stdcall img._.validate, [_img]
151
	or	eax, eax
152
	jnz	.error
153
 
154
	mov	esi, [_img]
155
	mov	ecx, [esi + Image.Width]
156
	imul	ecx, [esi + Image.Height]
157
	lea	eax, [ecx * 3 + 4 * 3]
158
	invoke	mem.alloc, eax
159
	or	eax, eax
160
	jz	.error
161
 
162
	mov	edi, eax
163
	push	eax
164
	mov	eax, [esi + Image.Width]
165
	stosd
166
	mov	eax, [esi + Image.Height]
167
	stosd
999 diamond 168
	mov	eax, [esi + Image.Type]
169
	dec	eax
170
	jz	.bpp8
171
	dec	eax
172
	jz	.bpp24
173
	dec	eax
174
	jnz	.error_pop
175
; 32 BPP -> 24 BPP
717 mikedld 176
	mov	esi, [esi + Image.Data]
177
 
178
    @@: dec	ecx
179
	js	@f
180
	movsd
181
	dec	edi
182
	jmp	@b
183
 
184
    @@: pop	eax
185
	pop	edi esi
186
	ret
187
 
999 diamond 188
.bpp24:
189
; 24 BPP -> 24 BPP
190
	lea	ecx, [ecx*3 + 3]
191
	mov	esi, [esi + Image.Data]
192
	shr	ecx, 2
193
	rep	movsd
194
	pop	eax
195
	pop	edi esi
196
	ret
197
 
198
.bpp8:
199
; 8 BPP -> 24 BPP
200
	push	ebx
201
	mov	ebx, [esi + Image.Palette]
202
	mov	esi, [esi + Image.Data]
203
@@:
204
	movzx	eax, byte [esi]
205
	add	esi, 1
206
	mov	eax, [ebx + eax*4]
207
	mov	[edi], eax
208
	add	edi, 3
209
	sub	ecx, 1
210
	jnz	@b
211
	pop	ebx
212
	pop	eax
213
	pop	edi esi
214
	ret
215
 
216
  .error_pop:
217
  	pop	eax
218
 
717 mikedld 219
  .error:
220
	xor	eax, eax
221
	pop	edi esi
222
	ret
223
endp
224
 
225
;;================================================================================================;;
226
proc img.decode _data, _length ;//////////////////////////////////////////////////////////////////;;
227
;;------------------------------------------------------------------------------------------------;;
228
;? --- TBD ---                                                                                    ;;
229
;;------------------------------------------------------------------------------------------------;;
230
;> --- TBD ---                                                                                    ;;
231
;;------------------------------------------------------------------------------------------------;;
232
;< eax = 0 / pointer to image                                                                     ;;
233
;;================================================================================================;;
234
	push	ebx
235
	mov	ebx, img._.formats_table
236
    @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
237
	or	eax, eax
238
	jnz	@f
239
	add	ebx, sizeof.FormatsTableEntry
240
	cmp	dword[ebx], 0
999 diamond 241
	jnz	@b
717 mikedld 242
	jmp	.error
243
    @@: stdcall [ebx + FormatsTableEntry.Decode], [_data], [_length]
244
 
245
  .error:
246
	ret
247
endp
248
 
249
;;================================================================================================;;
250
proc img.encode _img, _p_length ;/////////////////////////////////////////////////////////////////;;
251
;;------------------------------------------------------------------------------------------------;;
252
;? --- TBD ---                                                                                    ;;
253
;;------------------------------------------------------------------------------------------------;;
254
;> --- TBD ---                                                                                    ;;
255
;;------------------------------------------------------------------------------------------------;;
256
;< eax = 0 / pointer to encoded data                                                              ;;
257
;< [_p_length] = data length                                                                      ;;
258
;;================================================================================================;;
259
	xor	eax, eax
260
	ret
261
endp
262
 
263
;;================================================================================================;;
999 diamond 264
proc img.create _width, _height, _type ;//////////////////////////////////////////////////////////;;
717 mikedld 265
;;------------------------------------------------------------------------------------------------;;
266
;? --- TBD ---                                                                                    ;;
267
;;------------------------------------------------------------------------------------------------;;
268
;> --- TBD ---                                                                                    ;;
269
;;------------------------------------------------------------------------------------------------;;
270
;< eax = 0 / pointer to image                                                                     ;;
271
;;================================================================================================;;
272
	push	ecx
273
 
274
	stdcall img._.new
275
	or	eax, eax
276
	jz	.error
277
 
999 diamond 278
	mov	ecx, [_type]
279
	mov	[eax + Image.Type], ecx
280
 
717 mikedld 281
	push	eax
282
 
783 mikedld 283
	stdcall img._.resize_data, eax, [_width], [_height]
717 mikedld 284
	or	eax, eax
285
	jz	.error.2
286
 
287
	pop	eax
999 diamond 288
	jmp	.ret
717 mikedld 289
 
290
  .error.2:
291
;       pop     eax
292
	stdcall img._.delete; eax
293
	xor	eax, eax
294
 
295
  .error:
999 diamond 296
  .ret:
717 mikedld 297
	pop	ecx
298
	ret
299
endp
300
 
301
;;================================================================================================;;
302
proc img.destroy _img ;///////////////////////////////////////////////////////////////////////////;;
303
;;------------------------------------------------------------------------------------------------;;
304
;? --- TBD ---                                                                                    ;;
305
;;------------------------------------------------------------------------------------------------;;
306
;> --- TBD ---                                                                                    ;;
307
;;------------------------------------------------------------------------------------------------;;
308
;< eax = false / true                                                                             ;;
309
;;================================================================================================;;
310
	;TODO: link Next and Previous
311
	stdcall img._.delete, [_img]
312
	ret
313
endp
314
 
315
;;================================================================================================;;
783 mikedld 316
proc img.count _img ;/////////////////////////////////////////////////////////////////////////////;;
717 mikedld 317
;;------------------------------------------------------------------------------------------------;;
783 mikedld 318
;? Get number of images in the list (e.g. in animated GIF file)                                   ;;
717 mikedld 319
;;------------------------------------------------------------------------------------------------;;
783 mikedld 320
;> _img = pointer to image                                                                        ;;
717 mikedld 321
;;------------------------------------------------------------------------------------------------;;
783 mikedld 322
;< eax = -1 (fail) / >0 (ok)                                                                      ;;
717 mikedld 323
;;================================================================================================;;
783 mikedld 324
	push	ecx edx
325
	mov	edx, [_img]
326
	stdcall img._.validate, edx
717 mikedld 327
	or	eax, eax
783 mikedld 328
	jnz	.error
717 mikedld 329
 
783 mikedld 330
    @@: mov	eax, [edx + Image.Previous]
331
	or	eax, eax
332
	jz	@f
333
	mov	edx, eax
334
	jmp	@b
717 mikedld 335
 
783 mikedld 336
    @@: xor	ecx, ecx
337
    @@: inc	ecx
338
	mov	eax, [edx + Image.Next]
339
	or	eax, eax
340
	jz	.exit
341
	mov	edx, eax
342
	jmp	@b
343
 
344
  .exit:
345
	mov	eax, ecx
346
	pop	edx ecx
347
	ret
348
 
717 mikedld 349
  .error:
783 mikedld 350
	or	eax, -1
351
	pop	edx ecx
717 mikedld 352
	ret
353
endp
354
 
783 mikedld 355
;;//// image processing //////////////////////////////////////////////////////////////////////////;;
356
 
717 mikedld 357
;;================================================================================================;;
358
proc img.lock_bits _img, _start_line, _end_line ;/////////////////////////////////////////////////;;
359
;;------------------------------------------------------------------------------------------------;;
360
;? --- TBD ---                                                                                    ;;
361
;;------------------------------------------------------------------------------------------------;;
362
;> --- TBD ---                                                                                    ;;
363
;;------------------------------------------------------------------------------------------------;;
364
;< eax = 0 / pointer to bits                                                                      ;;
365
;;================================================================================================;;
366
	xor	eax, eax
367
	ret
368
endp
369
 
370
;;================================================================================================;;
371
proc img.unlock_bits _img, _lock ;////////////////////////////////////////////////////////////////;;
372
;;------------------------------------------------------------------------------------------------;;
373
;? --- TBD ---                                                                                    ;;
374
;;------------------------------------------------------------------------------------------------;;
375
;> --- TBD ---                                                                                    ;;
376
;;------------------------------------------------------------------------------------------------;;
377
;< eax = false / true                                                                             ;;
378
;;================================================================================================;;
379
	xor	eax, eax
380
	ret
381
endp
382
 
383
;;================================================================================================;;
384
proc img.flip _img, _flip_kind ;//////////////////////////////////////////////////////////////////;;
385
;;------------------------------------------------------------------------------------------------;;
783 mikedld 386
;? Flip image                                                                                     ;;
717 mikedld 387
;;------------------------------------------------------------------------------------------------;;
783 mikedld 388
;> _img = pointer to image                                                                        ;;
389
;> _flip_kind = one of FLIP_* constants                                                           ;;
717 mikedld 390
;;------------------------------------------------------------------------------------------------;;
783 mikedld 391
;< eax = false / true                                                                             ;;
717 mikedld 392
;;================================================================================================;;
393
locals
394
  scanline_len dd ?
395
endl
396
 
999 diamond 397
	push	ebx esi edi
398
	mov	ebx, [_img]
399
	stdcall img._.validate, ebx
717 mikedld 400
	or	eax, eax
401
	jnz	.error
402
 
999 diamond 403
	mov	ecx, [ebx + Image.Height]
404
	mov	eax, [ebx + Image.Width]
405
	call	img._.get_scanline_len
717 mikedld 406
	mov	[scanline_len], eax
407
 
408
	test	[_flip_kind], FLIP_VERTICAL
409
	jz	.dont_flip_vert
410
 
411
	imul	eax, ecx
412
	sub	eax, [scanline_len]
413
	shr	ecx, 1
999 diamond 414
	mov	esi, [ebx + Image.Data]
717 mikedld 415
	lea	edi, [esi + eax]
416
 
417
  .next_line_vert:
418
	push	ecx
419
 
420
	mov	ecx, [scanline_len]
999 diamond 421
	push	ecx
783 mikedld 422
	shr	ecx, 2
999 diamond 423
    @@: mov	eax, [esi]
717 mikedld 424
	xchg	eax, [edi]
999 diamond 425
	mov	[esi], eax
426
	add	esi, 4
717 mikedld 427
	add	edi, 4
999 diamond 428
	sub	ecx, 1
429
	jnz	@b
430
	pop	ecx
431
	and	ecx, 3
432
	jz	.cont_line_vert
433
    @@:
434
	mov	al, [esi]
435
	xchg	al, [edi]
436
	mov	[esi], al
437
	add	esi, 1
438
	add	edi, 1
783 mikedld 439
	dec	ecx
717 mikedld 440
	jnz	@b
999 diamond 441
    .cont_line_vert:
717 mikedld 442
 
783 mikedld 443
	pop	ecx
717 mikedld 444
	mov	eax, [scanline_len]
445
	shl	eax, 1
446
	sub	edi, eax
447
	dec	ecx
448
	jnz	.next_line_vert
449
 
450
  .dont_flip_vert:
451
 
452
	test	[_flip_kind], FLIP_HORIZONTAL
453
	jz	.exit
454
 
999 diamond 455
	mov	ecx, [ebx + Image.Height]
456
	mov	eax, [ebx + Image.Type]
457
	mov	esi, [ebx + Image.Data]
458
	mov	edi, [scanline_len]
459
	add	edi, esi
717 mikedld 460
 
999 diamond 461
	dec	eax
462
	jz	.bpp8.2
463
	dec	eax
464
	jz	.bpp24.2
465
 
466
	sub	edi, 4
467
 
783 mikedld 468
  .next_line_horz:
469
	push	ecx esi edi
470
 
471
	mov	ecx, [scanline_len]
472
	shr	ecx, 3
473
    @@: mov	eax, [esi]
474
	xchg	eax, [edi]
475
	mov	[esi], eax
476
	add	esi, 4
477
	add	edi, -4
999 diamond 478
	sub	ecx, 1
783 mikedld 479
	jnz	@b
480
 
481
	pop	edi esi ecx
482
	add	esi, [scanline_len]
483
	add	edi, [scanline_len]
484
	dec	ecx
485
	jnz	.next_line_horz
999 diamond 486
	jmp	.exit
783 mikedld 487
 
999 diamond 488
.bpp8.2:
489
	dec	edi
490
  .next_line_horz8:
491
	push	ecx esi edi
492
 
493
	mov	ecx, [scanline_len]
494
	shr	ecx, 1
495
    @@: mov	al, [esi]
496
	mov	dl, [edi]
497
	mov	[edi], al
498
	mov	[esi], dl
499
	add	esi, 1
500
	sub	edi, 1
501
	sub	ecx, 1
502
	jnz	@b
503
 
504
	pop	edi esi ecx
505
	add	esi, [scanline_len]
506
	add	edi, [scanline_len]
507
	dec	ecx
508
	jnz	.next_line_horz8
509
	jmp	.exit
510
 
511
.bpp24.2:
512
	sub	edi, 3
513
  .next_line_horz32:
514
	push	ecx esi edi
515
 
516
	mov	ecx, [ebx + Image.Width]
517
	shr	ecx, 1
518
    @@:
519
	mov	al, [esi]
520
	mov	dl, [edi]
521
	mov	[edi], al
522
	mov	[esi], dl
523
	mov	al, [esi+1]
524
	mov	dl, [edi+1]
525
	mov	[edi+1], al
526
	mov	[esi+1], dl
527
	mov	al, [esi+2]
528
	mov	dl, [edi+2]
529
	mov	[edi+2], al
530
	mov	[esi+2], dl
531
	add	esi, 3
532
	sub	edi, 3
533
	sub	ecx, 1
534
	jnz	@b
535
 
536
	pop	edi esi ecx
537
	add	esi, [scanline_len]
538
	add	edi, [scanline_len]
539
	dec	ecx
540
	jnz	.next_line_horz32
541
 
717 mikedld 542
  .exit:
543
	xor	eax, eax
544
	inc	eax
999 diamond 545
	pop	edi esi ebx
717 mikedld 546
	ret
547
 
548
  .error:
549
	xor	eax, eax
999 diamond 550
	pop	edi esi ebx
717 mikedld 551
	ret
552
endp
553
 
783 mikedld 554
;;================================================================================================;;
555
proc img.rotate _img, _rotate_kind ;//////////////////////////////////////////////////////////////;;
556
;;------------------------------------------------------------------------------------------------;;
557
;? Rotate image                                                                                   ;;
558
;;------------------------------------------------------------------------------------------------;;
559
;> _img = pointer to image                                                                        ;;
560
;> _rotate_kind = one of ROTATE_* constants                                                       ;;
561
;;------------------------------------------------------------------------------------------------;;
562
;< eax = false / true                                                                             ;;
563
;;================================================================================================;;
564
locals
565
  scanline_len_old    dd ?
566
  scanline_len_new    dd ?
567
  scanline_pixels_new dd ?
568
  line_buffer	      dd ?
569
  pixels_ptr	      dd ?
570
endl
717 mikedld 571
 
783 mikedld 572
	mov	[line_buffer], 0
573
 
574
	push	ebx esi edi
999 diamond 575
	mov	ebx, [_img]
576
	stdcall img._.validate, ebx
783 mikedld 577
	or	eax, eax
578
	jnz	.error
579
 
580
	cmp	[_rotate_kind], ROTATE_90_CCW
581
	je	.rotate_ccw_low
582
	cmp	[_rotate_kind], ROTATE_90_CW
583
	je	.rotate_cw_low
584
	cmp	[_rotate_kind], ROTATE_180
585
	je	.flip
586
	jmp	.exit
587
 
588
  .rotate_ccw_low:
589
	mov	eax, [ebx + Image.Height]
590
	mov	[scanline_pixels_new], eax
999 diamond 591
	call	img._.get_scanline_len
783 mikedld 592
	mov	[scanline_len_new], eax
593
 
594
	invoke	mem.alloc, eax
595
	or	eax, eax
596
	jz	.error
597
	mov	[line_buffer], eax
598
 
999 diamond 599
	mov	eax, [ebx + Image.Width]
600
	mov	ecx, eax
601
	call	img._.get_scanline_len
783 mikedld 602
	mov	[scanline_len_old], eax
603
 
604
	mov	eax, [scanline_len_new]
605
	imul	eax, ecx
606
	add	eax, [ebx + Image.Data]
607
	mov	[pixels_ptr], eax
608
 
999 diamond 609
	cmp	[ebx + Image.Type], Image.bpp8
610
	jz	.rotate_ccw8
611
	cmp	[ebx + Image.Type], Image.bpp24
612
	jz	.rotate_ccw24
613
 
783 mikedld 614
  .next_column_ccw_low:
615
	dec	ecx
999 diamond 616
	js	.exchange_dims
783 mikedld 617
	push	ecx
618
 
619
	mov	edx, [scanline_len_old]
620
	add	[scanline_len_old], -4
621
 
622
	mov	ecx, [scanline_pixels_new]
623
	mov	esi, [ebx + Image.Data]
624
	mov	edi, [line_buffer]
625
    @@: mov	eax, [esi]
626
	stosd
627
	add	esi, edx
628
	dec	ecx
629
	jnz	@b
630
 
631
	mov	eax, [scanline_pixels_new]
632
	mov	edi, [ebx + Image.Data]
633
	lea	esi, [edi + 4]
634
	mov	edx, [scanline_len_old]
635
	shr	edx, 2
636
    @@: mov	ecx, edx
637
	rep	movsd
638
	add	esi, 4
639
	dec	eax
640
	jnz	@b
641
 
642
	mov	eax, [scanline_len_new]
643
	sub	[pixels_ptr], eax
644
	mov	ecx, [scanline_pixels_new]
645
	mov	esi, [line_buffer]
646
	mov	edi, [pixels_ptr]
647
	rep	movsd
648
 
649
	pop	ecx
650
	jmp	.next_column_ccw_low
651
 
999 diamond 652
.rotate_ccw8:
653
  .next_column_ccw_low8:
654
	dec	ecx
655
	js	.exchange_dims
656
	push	ecx
657
 
658
	mov	edx, [scanline_len_old]
659
	add	[scanline_len_old], -1
660
 
661
	mov	ecx, [scanline_pixels_new]
662
	mov	esi, [ebx + Image.Data]
663
	mov	edi, [line_buffer]
664
    @@: mov	al, [esi]
665
	mov	[edi], al
666
	add	esi, edx
667
	add	edi, 1
668
	sub	ecx, 1
669
	jnz	@b
670
 
671
	mov	eax, [scanline_pixels_new]
672
	mov	edi, [ebx + Image.Data]
673
	lea	esi, [edi + 1]
674
	mov	edx, [scanline_len_old]
675
    @@: mov	ecx, edx
676
	shr	ecx, 2
677
	rep	movsd
678
	mov	ecx, edx
679
	and	ecx, 3
680
	rep	movsb
681
	add	esi, 1
682
	sub	eax, 1
683
	jnz	@b
684
 
685
	mov	eax, [scanline_len_new]
686
	sub	[pixels_ptr], eax
687
	mov	ecx, [scanline_pixels_new]
688
	mov	esi, [line_buffer]
689
	mov	edi, [pixels_ptr]
690
	mov	edx, ecx
691
	shr	ecx, 2
692
	rep	movsd
693
	mov	ecx, edx
694
	and	ecx, 3
695
	rep	movsb
696
 
697
	pop	ecx
698
	jmp	.next_column_ccw_low8
699
 
700
.rotate_ccw24:
701
  .next_column_ccw_low24:
702
	dec	ecx
703
	js	.exchange_dims
704
	push	ecx
705
 
706
	mov	edx, [scanline_len_old]
707
	add	[scanline_len_old], -3
708
 
709
	mov	ecx, [scanline_pixels_new]
710
	mov	esi, [ebx + Image.Data]
711
	mov	edi, [line_buffer]
712
    @@: mov	al, [esi]
713
	mov	[edi], al
714
	mov	al, [esi+1]
715
	mov	[edi+1], al
716
	mov	al, [esi+2]
717
	mov	[edi+2], al
718
	add	esi, edx
719
	add	edi, 3
720
	sub	ecx, 1
721
	jnz	@b
722
 
723
	mov	eax, [scanline_pixels_new]
724
	mov	edi, [ebx + Image.Data]
725
	lea	esi, [edi + 3]
726
	mov	edx, [scanline_len_old]
727
    @@: mov	ecx, edx
728
	shr	ecx, 2
729
	rep	movsd
730
	mov	ecx, edx
731
	and	ecx, 3
732
	rep	movsb
733
	add	esi, 3
734
	sub	eax, 1
735
	jnz	@b
736
 
737
	mov	eax, [scanline_len_new]
738
	sub	[pixels_ptr], eax
739
	mov	ecx, eax
740
	mov	esi, [line_buffer]
741
	mov	edi, [pixels_ptr]
742
	shr	ecx, 2
743
	rep	movsd
744
	mov	ecx, eax
745
	and	ecx, 3
746
	rep	movsb
747
 
748
	pop	ecx
749
	jmp	.next_column_ccw_low24
750
 
783 mikedld 751
  .rotate_cw_low:
752
	mov	eax, [ebx + Image.Height]
753
	mov	[scanline_pixels_new], eax
999 diamond 754
	call	img._.get_scanline_len
783 mikedld 755
	mov	[scanline_len_new], eax
756
 
757
	invoke	mem.alloc, eax
758
	or	eax, eax
759
	jz	.error
760
	mov	[line_buffer], eax
761
 
999 diamond 762
	mov	eax, [ebx + Image.Width]
763
	mov	ecx, eax
764
	call	img._.get_scanline_len
783 mikedld 765
	mov	[scanline_len_old], eax
766
 
767
	mov	eax, [scanline_len_new]
768
	imul	eax, ecx
769
	add	eax, [ebx + Image.Data]
770
	mov	[pixels_ptr], eax
771
 
999 diamond 772
	cmp	[ebx + Image.Type], Image.bpp8
773
	jz	.rotate_cw8
774
	cmp	[ebx + Image.Type], Image.bpp24
775
	jz	.rotate_cw24
776
 
783 mikedld 777
  .next_column_cw_low:
778
	dec	ecx
779
	js	.exchange_dims
780
	push	ecx
781
 
782
	mov	edx, [scanline_len_old]
783
	add	[scanline_len_old], -4
784
 
785
	mov	ecx, [scanline_pixels_new]
786
	mov	esi, [pixels_ptr]
787
	add	esi, -4
788
	mov	edi, [line_buffer]
789
    @@: mov	eax, [esi]
790
	stosd
791
	sub	esi, edx
792
	dec	ecx
793
	jnz	@b
794
 
795
	mov	eax, [scanline_pixels_new]
796
	dec	eax
797
	mov	edi, [ebx + Image.Data]
798
	add	edi, [scanline_len_old]
799
	lea	esi, [edi + 4]
800
	mov	edx, [scanline_len_old]
801
	shr	edx, 2
802
    @@: mov	ecx, edx
803
	rep	movsd
804
	add	esi, 4
805
	dec	eax
806
	jnz	@b
807
 
808
	mov	eax, [scanline_len_new]
809
	sub	[pixels_ptr], eax
810
	mov	ecx, [scanline_pixels_new]
811
	mov	esi, [line_buffer]
812
	mov	edi, [pixels_ptr]
813
	rep	movsd
814
 
815
	pop	ecx
816
	jmp	.next_column_cw_low
817
 
999 diamond 818
.rotate_cw8:
819
  .next_column_cw_low8:
820
	dec	ecx
821
	js	.exchange_dims
822
	push	ecx
823
 
824
	mov	edx, [scanline_len_old]
825
	add	[scanline_len_old], -1
826
 
827
	mov	ecx, [scanline_pixels_new]
828
	mov	esi, [pixels_ptr]
829
	add	esi, -1
830
	mov	edi, [line_buffer]
831
    @@: mov	al, [esi]
832
	mov	[edi], al
833
	sub	esi, edx
834
	add	edi, 1
835
	sub	ecx, 1
836
	jnz	@b
837
 
838
	mov	eax, [scanline_pixels_new]
839
	dec	eax
840
	mov	edi, [ebx + Image.Data]
841
	add	edi, [scanline_len_old]
842
	lea	esi, [edi + 1]
843
	mov	edx, [scanline_len_old]
844
    @@: mov	ecx, edx
845
	shr	ecx, 2
846
	rep	movsd
847
	mov	ecx, edx
848
	and	ecx, 3
849
	rep	movsb
850
	add	esi, 1
851
	sub	eax, 1
852
	jnz	@b
853
 
854
	mov	eax, [scanline_len_new]
855
	sub	[pixels_ptr], eax
856
	mov	ecx, eax
857
	mov	esi, [line_buffer]
858
	mov	edi, [pixels_ptr]
859
	shr	ecx, 2
860
	rep	movsd
861
	mov	ecx, eax
862
	and	ecx, 3
863
	rep	movsb
864
 
865
	pop	ecx
866
	jmp	.next_column_cw_low8
867
 
868
.rotate_cw24:
869
  .next_column_cw_low24:
870
	dec	ecx
871
	js	.exchange_dims
872
	push	ecx
873
 
874
	mov	edx, [scanline_len_old]
875
	add	[scanline_len_old], -3
876
 
877
	mov	ecx, [scanline_pixels_new]
878
	mov	esi, [pixels_ptr]
879
	add	esi, -3
880
	mov	edi, [line_buffer]
881
    @@: mov	al, [esi]
882
	mov	[edi], al
883
	mov	al, [esi+1]
884
	mov	[edi+1], al
885
	mov	al, [esi+2]
886
	mov	[edi+2], al
887
	sub	esi, edx
888
	add	edi, 3
889
	sub	ecx, 1
890
	jnz	@b
891
 
892
	mov	eax, [scanline_pixels_new]
893
	dec	eax
894
	mov	edi, [ebx + Image.Data]
895
	add	edi, [scanline_len_old]
896
	lea	esi, [edi + 3]
897
	mov	edx, [scanline_len_old]
898
    @@: mov	ecx, edx
899
	shr	ecx, 2
900
	rep	movsd
901
	mov	ecx, edx
902
	and	ecx, 3
903
	rep	movsb
904
	add	esi, 3
905
	sub	eax, 1
906
	jnz	@b
907
 
908
	mov	eax, [scanline_len_new]
909
	sub	[pixels_ptr], eax
910
	mov	ecx, eax
911
	mov	esi, [line_buffer]
912
	mov	edi, [pixels_ptr]
913
	shr	ecx, 2
914
	rep	movsd
915
	mov	ecx, eax
916
	and	ecx, 3
917
	rep	movsb
918
 
919
	pop	ecx
920
	jmp	.next_column_cw_low24
921
 
783 mikedld 922
  .flip:
923
	jmp	.exit
924
 
925
  .exchange_dims:
926
	push	[ebx + Image.Width] [ebx + Image.Height]
927
	pop	[ebx + Image.Width] [ebx + Image.Height]
928
 
929
  .exit:
930
	invoke	mem.free, [line_buffer]
931
	xor	eax, eax
932
	inc	eax
933
	pop	edi esi ebx
934
	ret
935
 
936
  .error:
937
	invoke	mem.free, [line_buffer]
938
	xor	eax, eax
939
	pop	edi esi ebx
940
	ret
941
endp
942
 
943
 
717 mikedld 944
;;================================================================================================;;
945
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
946
;;================================================================================================;;
947
;! Below are private procs you should never call directly from your code                          ;;
948
;;================================================================================================;;
949
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
950
;;================================================================================================;;
951
 
952
 
953
;;================================================================================================;;
954
proc img._.validate, _img ;///////////////////////////////////////////////////////////////////////;;
955
;;------------------------------------------------------------------------------------------------;;
956
;? --- TBD ---                                                                                    ;;
957
;;------------------------------------------------------------------------------------------------;;
958
;> --- TBD ---                                                                                    ;;
959
;;------------------------------------------------------------------------------------------------;;
960
;< --- TBD ---                                                                                    ;;
961
;;================================================================================================;;
962
	xor	eax, eax
963
	ret
964
endp
965
 
966
;;================================================================================================;;
967
proc img._.new ;//////////////////////////////////////////////////////////////////////////////////;;
968
;;------------------------------------------------------------------------------------------------;;
969
;? --- TBD ---                                                                                    ;;
970
;;------------------------------------------------------------------------------------------------;;
971
;> --- TBD ---                                                                                    ;;
972
;;------------------------------------------------------------------------------------------------;;
973
;< eax = 0 / pointer to image                                                                     ;;
974
;;================================================================================================;;
975
	invoke	mem.alloc, sizeof.Image
999 diamond 976
	test	eax, eax
977
	jz	@f
978
	push	ecx
979
	xor	ecx, ecx
980
	mov	[eax + Image.Data], ecx
981
	mov	[eax + Image.Type], ecx
982
	mov	[eax + Image.Extended], ecx
983
	mov	[eax + Image.Previous], ecx
984
	mov	[eax + Image.Next], ecx
985
	pop	ecx
986
@@:
717 mikedld 987
	ret
988
endp
989
 
990
;;================================================================================================;;
991
proc img._.delete _img ;//////////////////////////////////////////////////////////////////////////;;
992
;;------------------------------------------------------------------------------------------------;;
993
;? --- TBD ---                                                                                    ;;
994
;;------------------------------------------------------------------------------------------------;;
995
;> --- TBD ---                                                                                    ;;
996
;;------------------------------------------------------------------------------------------------;;
997
;< eax = false / true                                                                             ;;
998
;;================================================================================================;;
999
	push	edx
1000
	mov	edx, [_img]
1001
	cmp	[edx + Image.Data], 0
1002
	je	@f
1003
	invoke	mem.free, [edx + Image.Data]
1004
    @@: cmp	[edx + Image.Extended], 0
1005
	je	@f
1006
	invoke	mem.free, [edx + Image.Extended]
1007
    @@: invoke	mem.free, edx
1008
	pop	edx
1009
	ret
1010
endp
1011
 
783 mikedld 1012
;;================================================================================================;;
1013
proc img._.resize_data _img, _width, _height ;////////////////////////////////////////////////////;;
1014
;;------------------------------------------------------------------------------------------------;;
1015
;? --- TBD ---                                                                                    ;;
1016
;;------------------------------------------------------------------------------------------------;;
1017
;> --- TBD ---                                                                                    ;;
1018
;;------------------------------------------------------------------------------------------------;;
1019
;< --- TBD ---                                                                                    ;;
1020
;;================================================================================================;;
999 diamond 1021
	push	ebx esi
783 mikedld 1022
	mov	ebx, [_img]
1023
	mov	eax, [_height]
999 diamond 1024
; our memory is limited, [_width]*[_height] must not overflow
1025
; image with width or height greater than 65535 is most likely bogus
1026
	cmp	word [_width+2], 0
1027
	jnz	.error
1028
	cmp	word [_height+2], 0
1029
	jnz	.error
783 mikedld 1030
	imul	eax, [_width]
999 diamond 1031
	test	eax, eax
1032
	jz	.error
1033
; do not allow images which require too many memory
1034
	cmp	eax, 4000000h
1035
	jae	.error
1036
	cmp	[ebx + Image.Type], Image.bpp8
1037
	jz	.bpp8
1038
	cmp	[ebx + Image.Type], Image.bpp24
1039
	jz	.bpp24
1040
.bpp32:
783 mikedld 1041
	shl	eax, 2
999 diamond 1042
	jmp	@f
1043
.bpp24:
1044
	lea	eax, [eax*3]
1045
	jmp	@f
1046
.bpp8:
1047
	add	eax, 256*4	; for palette
1048
@@:
1049
	mov	esi, eax
783 mikedld 1050
	invoke	mem.realloc, [ebx + Image.Data], eax
1051
	or	eax, eax
1052
	jz	.error
717 mikedld 1053
 
783 mikedld 1054
	mov	[ebx + Image.Data], eax
1055
	push	[_width]
1056
	pop	[ebx + Image.Width]
1057
	push	[_height]
1058
	pop	[ebx + Image.Height]
999 diamond 1059
	cmp	[ebx + Image.Type], Image.bpp8
1060
	jnz	.ret
1061
	lea	esi, [eax + esi - 256*4]
1062
	mov	[ebx + Image.Palette], esi
1063
	jmp	.ret
783 mikedld 1064
 
1065
  .error:
999 diamond 1066
	xor	eax, eax
1067
  .ret:
1068
	pop	esi ebx
783 mikedld 1069
	ret
1070
endp
1071
 
999 diamond 1072
;;================================================================================================;;
1073
img._.get_scanline_len: ;/////////////////////////////////////////////////////////////////////////;;
1074
;;------------------------------------------------------------------------------------------------;;
1075
;? --- TBD ---                                                                                    ;;
1076
;;------------------------------------------------------------------------------------------------;;
1077
;> --- TBD ---                                                                                    ;;
1078
;;------------------------------------------------------------------------------------------------;;
1079
;< --- TBD ---                                                                                    ;;
1080
;;================================================================================================;;
1081
	cmp	[ebx + Image.Type], Image.bpp8
1082
	jz	.bpp8.1
1083
	cmp	[ebx + Image.Type], Image.bpp24
1084
	jz	.bpp24.1
1085
	shl	eax, 2
1086
	jmp	@f
1087
.bpp24.1:
1088
	lea	eax, [eax*3]
1089
.bpp8.1:
1090
@@:
1091
	ret
783 mikedld 1092
 
999 diamond 1093
 
717 mikedld 1094
;;================================================================================================;;
1095
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1096
;;================================================================================================;;
1097
;! Below is private data you should never use directly from your code                             ;;
1098
;;================================================================================================;;
1099
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1100
;;================================================================================================;;
1101
 
1102
 
1103
img._.formats_table:
1104
  .bmp dd img.is.bmp, img.decode.bmp, img.encode.bmp
1105
; .ico dd img.is.ico, img.decode.ico, img.encode.ico
1106
; .cur dd img.is.cur, img.decode.cur, img.encode.cur
1107
  .gif dd img.is.gif, img.decode.gif, img.encode.gif
1108
; .png dd img.is.png, img.decode.png, img.encode.png
999 diamond 1109
  .jpg dd img.is.jpg, img.decode.jpg, img.encode.jpg
717 mikedld 1110
       dd 0
1111
 
1112
 
1113
;;================================================================================================;;
1114
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1115
;;================================================================================================;;
1116
;! Exported functions section                                                                     ;;
1117
;;================================================================================================;;
1118
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1119
;;================================================================================================;;
1120
 
1121
 
999 diamond 1122
align 4
717 mikedld 1123
@EXPORT:
1124
 
1125
export					      \
1126
	lib_init	, 'lib_init'	    , \
1127
	0x00010001	, 'version'	    , \
1128
	img.is_img	, 'img.is_img'	    , \
1129
	img.info	, 'img.info'	    , \
1130
	img.from_file	, 'img.from_file'   , \
1131
	img.to_file	, 'img.to_file'     , \
1132
	img.from_rgb	, 'img.from_rgb'    , \
1133
	img.to_rgb	, 'img.to_rgb'	    , \
1134
	img.decode	, 'img.decode'	    , \
1135
	img.encode	, 'img.encode'	    , \
1136
	img.create	, 'img.create'	    , \
1137
	img.destroy	, 'img.destroy'     , \
783 mikedld 1138
	img.count	, 'img.count'	    , \
717 mikedld 1139
	img.lock_bits	, 'img.lock_bits'   , \
783 mikedld 1140
	img.unlock_bits , 'img.unlock_bits' , \
1141
	img.flip	, 'img.flip'	    , \
1142
	img.rotate	, 'img.rotate'
999 diamond 1143
 
1144
section '.data' data readable writable align 16
1145
; uninitialized data - global constant tables
1146
 
1147
; data for YCbCr -> RGB translation
1148
color_table_1		rd	256
1149
color_table_2		rd	256
1150
color_table_3		rd	256
1151
color_table_4		rd	256