Subversion Repositories Kolibri OS

Rev

Rev 3053 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3036 dunkaist 1
;;================================================================================================;;
2
;;//// scale.asm //// (c) dunkaist, 2012 /////////////////////////////////////////////////////////;;
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 ;;
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.                                         ;;
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  ;;
13
;; Lesser General Public License for more details.                                                ;;
14
;;                                                                                                ;;
15
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
16
;; If not, see .                                                    ;;
17
;;                                                                                                ;;
18
;;================================================================================================;;
19
 
20
;;================================================================================================;;
21
proc img.scale _src, _crop_x, _crop_y, _crop_width, _crop_height, _dst, _scale_type, _scale_alg, _param1, _param2 ;;
22
;;------------------------------------------------------------------------------------------------;;
23
;? scale _image                                                                                   ;;
24
;;------------------------------------------------------------------------------------------------;;
25
;> [_src]         = pointer to source image                                                       ;;
26
;> [_crop_x]      = left coord of cropping rect                                                   ;;
27
;> [_crop_y]      = top coord of cropping rect                                                    ;;
28
;> [_crop_width]  = width of cropping rect                                                        ;;
29
;> [_crop_height] = height of cropping rect                                                       ;;
30
;> [_dst]         = pointer to resulting image / 0                                                ;;
31
;> [_scale_type]  = how to change width and height. see libimg.inc                                ;;
32
;> [_scale_alg]   = algorithm to use. see libimg.inc                                              ;;
33
;> [_param1]      = the first argument passed to _scale_alg algorithm                             ;;
34
;> [_param2]      = the second argument passed to _scale_alg algorithm                            ;;
35
;;------------------------------------------------------------------------------------------------;;
36
;< eax = 0 / pointer to scaled image                                                              ;;
37
;< ecx = error code / undefined                                                                   ;;
38
;;================================================================================================;;
39
locals
40
	src_type		rd 1
41
	src_data		rd 1
42
	dst_data		rd 1
43
 
44
	src_width_pixels	rd 1
45
	src_width_bytes		rd 1
46
	src_height_pixels	rd 1
47
 
48
	scl_width_pixels	rd 1
49
	scl_width_pixels_inv	rd 1
50
	scl_height_pixels	rd 1
51
	scl_height_pixels_inv	rd 1
52
	scl_width_bytes		rd 1
53
	bytes_per_pixel		rd 1
54
 
55
	crop_width_pixels_m1	rd 1
56
	crop_height_pixels_m1	rd 1
57
; bilinear
58
	src_x			rd 1
59
	src_y			rd 1
60
	src_base		rd 1
61
	dst_x			rd 1
62
	dst_y			rd 1
63
	rem_x			rd 1
64
	rem_y			rd 1
65
endl
66
	mov	ebx, [_src]
67
	push	[ebx + Image.Width]
68
	pop	[src_width_pixels]
69
	push	[ebx + Image.Height]
70
	pop	[src_height_pixels]
71
	push	[ebx + Image.Type]
72
	pop	[src_type]
73
	push	[ebx + Image.Data]
74
	pop	[src_data]
75
 
76
	mov	eax, [src_type]
77
	mov	ecx, [src_width_pixels]
78
	mov	edx, [src_width_pixels]
79
	imul	edx, [_crop_y]
80
	add	edx, [_crop_x]
81
	cmp	eax, Image.bpp32
82
	jne	@f
83
	mov	[bytes_per_pixel], 4
84
	shl	ecx, 2
85
	shl	edx, 2
86
	jmp	.lab1
87
    @@:
88
	cmp	eax, Image.bpp24
89
	jne	@f
90
	mov	[bytes_per_pixel], 3
91
	lea	ecx, [ecx*3]
92
	lea	edx, [ecx*3]
93
	jmp	.lab1
94
    @@:
95
	cmp	eax, Image.bpp8g
96
	jne	@f
97
	mov	[bytes_per_pixel], 1
98
	jmp	.lab1
99
    @@:
100
	mov	ecx, LIBIMG_ERROR_BIT_DEPTH
101
	jmp	.error
102
  .lab1:
103
	mov	[src_width_bytes], ecx
104
	add	[src_data], edx
105
 
106
 
107
	mov	eax, [_scale_alg]
108
	cmp	eax, LIBIMG_SCALE_ALG_INTEGER
109
	je	.integer
110
	cmp	eax, LIBIMG_SCALE_ALG_BILINEAR
111
	je	.bilinear
112
	mov	ecx, LIBIMG_ERROR_SCALE_ALG
113
	jmp	.error
114
 
115
  .integer:
116
	mov	eax, [_param1]
117
	mov	ecx, [_crop_width]
118
	imul	ecx, eax
119
	mov	[scl_width_pixels], ecx
120
	mov	edx, [_crop_height]
121
	imul	edx, eax
122
	mov	[scl_height_pixels], edx
123
 
124
	mov	eax, [_dst]
125
	test	eax, eax
126
	jnz	@f
127
	stdcall	img.create, [scl_width_pixels], [scl_height_pixels], [src_type]
128
	test	eax, eax
129
	jz	.error
130
	mov	[_dst], eax
131
    @@:
132
	mov	edi, [eax + Image.Data]
133
	mov	[dst_data], edi
134
 
135
	mov	esi, [src_data]
136
	mov	eax, [src_type]
137
	cmp	eax, Image.bpp8g
138
	je	.integer.bpp8g
139
	cmp	eax, Image.bpp24
140
	je	.integer.bpp24
141
	cmp	eax, Image.bpp32
142
	je	.integer.bpp32
143
	mov	ecx, LIBIMG_ERROR_BIT_DEPTH
144
	jmp	.error
145
 
146
  .integer.bpp8g:
147
	push	[scl_width_pixels]
148
	pop	[scl_width_bytes]
149
	mov	ecx, [_param1]
150
;	cmp	ecx, 1
151
;	je	.error
152
  .integer.bpp8g.common:
153
	mov	edx, ecx
154
	mov	ebx, [_crop_height]
155
  .integer.bpp8g.common.line:
156
	push	ebx
157
	mov	ebx, [_crop_width]
158
    @@:
159
	lodsb
160
	mov	ecx, edx
161
	rep	stosb
162
	dec	ebx
163
	jnz	@b
164
	push	esi
165
	mov	esi, edi
166
	sub	esi, [scl_width_bytes]
167
	mov	ecx, edx
168
	dec	ecx
169
	imul	ecx, [scl_width_bytes]
170
	mov	eax, ecx
171
	shr	ecx, 2
172
	and	eax, 0x00000003
173
	rep	movsd
174
	mov	ecx, eax
175
	rep	movsb
176
	pop	esi
177
	mov	eax, [src_width_pixels]
178
	sub	eax, [_crop_width]
179
	add	esi, eax
180
	pop	ebx
181
	dec	ebx
182
	jnz	.integer.bpp8g.common.line
183
	mov	eax, [_dst]
184
	jmp	.quit
185
 
186
  .integer.bpp24:
187
	mov	eax, [scl_width_pixels]
188
	lea	eax, [eax*3]
189
	mov	[scl_width_bytes], eax
190
	mov	ecx, [_param1]
191
;	cmp	ecx, 1
192
;	je	.error
193
  .integer.bpp24.common:
194
	mov	edx, ecx
195
	mov	ebx, [_crop_height]
196
  .integer.bpp24.common.line:
197
	push	ebx
198
	mov	ebx, [_crop_width]
199
    @@:
200
	movsw
201
	movsb
202
	mov	ecx, edx
203
	push	esi
204
	mov	esi, edi
205
	sub	esi, 3
206
	dec	ecx
207
	lea	ecx, [ecx*3]
208
	rep	movsb
209
	pop	esi
210
	dec	ebx
211
	jnz	@b
212
	push	esi
213
	mov	esi, edi
214
	sub	esi, [scl_width_bytes]
215
	mov	ecx, edx
216
	dec	ecx
217
	imul	ecx, [scl_width_bytes]
218
	mov	eax, ecx
219
	shr	ecx, 2
220
	and	eax, 0x00000003
221
	rep	movsd
222
	mov	ecx, eax
223
	rep	movsb
224
	pop	esi
225
	mov	eax, [src_width_pixels]
226
	sub	eax, [_crop_width]
227
	lea	eax, [eax*3]
228
	add	esi, eax
229
	pop	ebx
230
	dec	ebx
231
	jnz	.integer.bpp24.common.line
232
	mov	eax, [_dst]
233
	jmp	.quit
234
 
235
  .integer.bpp32:
236
	mov	eax, [scl_width_pixels]
237
	shl	eax, 2
238
	mov	[scl_width_bytes], eax
239
	mov	ecx, [_param1]
240
;	cmp	ecx, 1
241
;	je	.error
242
  .integer.bpp32.common:
243
	mov	edx, ecx
244
	mov	ebx, [_crop_height]
245
  .integer.bpp32.common.line:
246
	push	ebx
247
	mov	ebx, [_crop_width]
248
    @@:
249
	lodsd
250
	mov	ecx, edx
251
	rep	stosd
252
	dec	ebx
253
	jnz	@b
254
	push	esi
255
	mov	esi, edi
256
	sub	esi, [scl_width_bytes]
257
	mov	ecx, edx
258
	dec	ecx
259
	imul	ecx, [scl_width_bytes]
260
	shr	ecx, 2
261
	rep	movsd
262
	pop	esi
263
	mov	eax, [src_width_pixels]
264
	sub	eax, [_crop_width]
265
	shl	eax, 2
266
	add	esi, eax
267
	pop	ebx
268
	dec	ebx
269
	jnz	.integer.bpp32.common.line
270
	mov	eax, [_dst]
271
	jmp	.quit
272
 
273
 
274
  .bilinear:
275
	mov	eax, [_scale_type]
276
	cmp	eax, LIBIMG_SCALE_TYPE_FIT_RECT
277
	je	.bilinear.fit_rect
278
	cmp	eax, LIBIMG_SCALE_TYPE_FIT_WIDTH
279
	je	.bilinear.fit_width
280
	cmp	eax, LIBIMG_SCALE_TYPE_FIT_HEIGHT
281
	je	.bilinear.fit_height
282
	cmp	eax, LIBIMG_SCALE_TYPE_FIT_MAX
283
	je	.bilinear.fit_max
284
	cmp	eax, LIBIMG_SCALE_TYPE_STRETCH
285
	je	.bilinear.stretch
286
	mov	ecx, LIBIMG_ERROR_SCALE_TYPE
287
	jmp	.error
288
  .bilinear.fit_rect:
289
	mov	eax, [_param1]
290
	shl	eax, 16
291
	add	eax, 0x00008000
292
	xor	edx, edx
293
	div	[src_width_pixels]
294
	mov	ebx, eax
295
	mov	eax, [_param2]
296
	shl	eax, 16
297
	add	eax, 0x00008000
298
	xor	edx, edx
299
	div	[src_height_pixels]
300
	mov	ecx, eax
301
	cmp	ebx, ecx
302
	jb	@f
303
	mov	ebx, ecx
304
    @@:
305
	jmp	.bilinear.fit_common
306
  .bilinear.fit_max:
307
	mov	eax, [_param1]
308
	shl	eax, 16
309
	add	eax, 0x00008000
310
	xor	edx, edx
311
	div	[src_width_pixels]
312
	mov	ebx, eax
313
	mov	eax, [_param2]
314
	shl	eax, 16
315
	add	eax, 0x00008000
316
	xor	edx, edx
317
	div	[src_height_pixels]
318
	mov	ecx, eax
319
	cmp	ebx, ecx
320
	ja	@f
321
	mov	ebx, ecx
322
    @@:
323
	jmp	.bilinear.fit_common
324
  .bilinear.fit_width:
325
	mov	eax, [_param1]
326
	shl	eax, 16
327
	add	eax, 0x00008000
328
	xor	edx, edx
329
	div	[src_width_pixels]
330
	mov	ebx, eax
331
	jmp	.bilinear.fit_common
332
  .bilinear.fit_height:
333
	mov	eax, [_param2]
334
	shl	eax, 16
335
	add	eax, 0x00008000
336
	xor	edx, edx
337
	div	[src_height_pixels]
338
	mov	ebx, eax
339
	jmp	.bilinear.fit_common
340
  .bilinear.fit_common:
341
	mov	eax, [src_width_pixels]
342
	mul	ebx
343
	shr	eax, 16
344
	mov	[scl_width_pixels], eax
345
	imul	eax, [bytes_per_pixel]
346
	mov	[scl_width_bytes], eax
347
	mov	eax, [src_height_pixels]
348
	mul	ebx
349
	shr	eax, 16
350
	mov	[scl_height_pixels], eax
351
	jmp	.bilinear.common
352
  .bilinear.stretch:
353
	mov	eax, [_param1]
354
	mov	[scl_width_pixels], eax
355
	imul	eax, [bytes_per_pixel]
356
	mov	[scl_width_bytes], eax
357
	mov	ecx, [_param2]
358
	mov	[scl_height_pixels], ecx
359
	jmp	.bilinear.common
360
 
361
  .bilinear.common:
362
	mov	eax, [_dst]
363
	test	eax, eax
364
	jnz	@f
365
	stdcall	img.create, [scl_width_pixels], [scl_height_pixels], [src_type]
366
	test	eax, eax
367
	jz	.error
368
	mov	[_dst], eax
369
    @@:
370
	mov	edi, [eax + Image.Data]
371
	mov	[dst_data], edi
372
 
373
	push	[_crop_width]
374
	pop	[crop_width_pixels_m1]
375
	sub	[crop_width_pixels_m1], 1
376
	push	[_crop_height]
377
	pop	[crop_height_pixels_m1]
378
	sub	[crop_height_pixels_m1], 1
379
 
380
	mov	eax, 0xffffffff
381
	xor	edx, edx
382
	div	[scl_width_pixels]
383
	mov	[scl_width_pixels_inv], eax
384
	mov	eax, 0xffffffff
385
	xor	edx, edx
386
	div	[scl_height_pixels]
387
	mov	[scl_height_pixels_inv], eax
388
 
389
	mov	eax, [src_type]
390
	cmp	eax, Image.bpp8g
391
	je	.bilinear.bpp8g
392
	cmp	eax, Image.bpp24
393
	je	.bilinear.bpp24
394
	cmp	eax, Image.bpp32
395
	je	.bilinear.bpp32
396
	mov	ecx, LIBIMG_ERROR_BIT_DEPTH
397
	jmp	.error
398
 
399
  .bilinear.bpp8g:
400
	mov	esi, [src_data]
401
	mov	[dst_y], 0
402
	mov	eax, 0	; mov eax, [dst_y]
403
  .bilinear.bpp8g.line:
404
	mov	esi, [src_data]
405
	mov	[dst_x], 0
406
	imul	eax, [crop_height_pixels_m1]
407
	xor	edx, edx
408
	div	[scl_height_pixels]
409
	mov	[rem_y], edx
410
	imul	eax, [src_width_bytes]
411
	add	esi, eax
412
	mov	[src_base], esi
413
	mov	eax, 0	; mov eax, [dst_x]
414
 
415
  .bilinear.bpp8g.pixel:
416
	mov	esi, [src_base]
417
 
418
	imul	eax, [crop_width_pixels_m1]
419
	xor	edx, edx
420
	div	[scl_width_pixels]
421
	add	esi, eax
422
 
423
	mov	ax, word[esi]
424
	add	esi, [src_width_pixels]
425
	mov	bx, word[esi]
426
	mov	esi, edx
427
	movzx	edx, ah
428
	and	eax, 0x000000ff
429
	movzx	ecx, bh
430
	and	ebx, 0x000000ff
431
 
432
	imul	edx, esi
433
	imul	ecx, esi
434
	neg	esi
435
	add	esi, [scl_width_pixels]
436
	imul	eax, esi
437
	imul	ebx, esi
438
	add	eax, edx
439
	add	ebx, ecx
440
	mov	esi, [scl_width_pixels_inv]
441
	mul	esi
442
	mov	ecx, edx
443
	mov	eax, ebx
444
	mul	esi
445
	mov	eax, edx
446
 
447
	mov	edx, [rem_y]
448
	imul	eax, edx
449
	neg	edx
450
	add	edx, [scl_height_pixels]
451
	imul	ecx, edx
452
	add	eax, ecx
453
	mul	[scl_height_pixels_inv]
454
	mov	byte[edi], dl
455
	add	edi, 1
456
 
457
	add	[dst_x], 1
458
	mov	eax, [dst_x]
459
	cmp	eax, [scl_width_pixels]
460
	jne	.bilinear.bpp8g.pixel
461
 
462
	add	[dst_y], 1
463
	mov	eax, [dst_y]
464
	cmp	eax, [scl_height_pixels]
465
	jne	.bilinear.bpp8g.line
466
 
467
	mov	eax, [_dst]
468
	jmp	.quit
469
 
470
 
471
  .bilinear.bpp24:
472
	mov	esi, [src_data]
473
	mov	[dst_y], 0
474
	mov	eax, 0	; mov eax, [dst_y]
475
  .bilinear.bpp24.line:
476
	mov	esi, [src_data]
477
	mov	[dst_x], 0
478
	imul	eax, [crop_height_pixels_m1]
479
	xor	edx, edx
480
	div	[scl_height_pixels]
481
	mov	[rem_y], edx
482
	imul	eax, [src_width_bytes]
483
	add	esi, eax
484
	mov	[src_base], esi
485
	mov	eax, 0	; mov eax, [dst_x]
486
 
487
  .bilinear.bpp24.pixel:
488
	mov	esi, [src_base]
489
 
490
	imul	eax, [crop_width_pixels_m1]
491
	xor	edx, edx
492
	div	[scl_width_pixels]
493
	lea	eax, [eax*3]
494
	add	esi, eax
495
 
496
	mov	[rem_x], edx
497
	sub	esi, 1
498
	mov	[src_x], esi
499
 
500
repeat 3
501
	mov	edx, [rem_x]
502
	add	[src_x], 1
503
	mov	esi, [src_x]
504
 
505
	mov	al, byte[esi]
506
	mov	ah, byte[esi + 3]
507
	add	esi, [src_width_bytes]
508
	movzx	ebx, byte[esi]
509
	movzx	ecx, byte[esi + 3]
510
	mov	esi, edx
511
	movzx	edx, ah
512
	and	eax, 0x000000ff
513
 
514
	imul	edx, esi
515
	imul	ecx, esi
516
	neg	esi
517
	add	esi, [scl_width_pixels]
518
	imul	eax, esi
519
	imul	ebx, esi
520
	add	eax, edx
521
	add	ebx, ecx
522
	mov	esi, [scl_width_pixels_inv]
523
	mul	esi
524
	mov	ecx, edx
525
	mov	eax, ebx
526
	mul	esi
527
	mov	eax, edx
528
 
529
	mov	edx, [rem_y]
530
	imul	eax, edx
531
	neg	edx
532
	add	edx, [scl_height_pixels]
533
	imul	ecx, edx
534
	add	eax, ecx
535
	mul	[scl_height_pixels_inv]
536
	mov	byte[edi], dl
537
	add	edi, 1
538
end repeat
539
 
540
	add	[dst_x], 1
541
	mov	eax, [dst_x]
542
	cmp	eax, [scl_width_pixels]
543
	jne	.bilinear.bpp24.pixel
544
 
545
	add	[dst_y], 1
546
	mov	eax, [dst_y]
547
	cmp	eax, [scl_height_pixels]
548
	jne	.bilinear.bpp24.line
549
 
550
	mov	eax, [_dst]
551
	jmp	.quit
552
 
553
  .bilinear.bpp32:
554
	mov	esi, [src_data]
555
	mov	[dst_y], 0
556
	mov	eax, 0	; mov eax, [dst_y]
557
  .bilinear.bpp32.line:
558
	mov	esi, [src_data]
559
	mov	[dst_x], 0
560
	imul	eax, [crop_height_pixels_m1]
561
	xor	edx, edx
562
	div	[scl_height_pixels]
563
	mov	[rem_y], edx
564
	imul	eax, [src_width_bytes]
565
	add	esi, eax
566
	mov	[src_base], esi
567
	mov	eax, 0	; mov eax, [dst_x]
568
 
569
  .bilinear.bpp32.pixel:
570
	mov	esi, [src_base]
571
 
572
	imul	eax, [crop_width_pixels_m1]
573
	xor	edx, edx
574
	div	[scl_width_pixels]
575
	shl	eax, 2
576
	add	esi, eax
577
 
578
	mov	[rem_x], edx
579
	sub	esi, 1
580
	mov	[src_x], esi
581
 
582
repeat 4
583
	mov	edx, [rem_x]
584
	add	[src_x], 1
585
	mov	esi, [src_x]
586
 
587
	mov	al, byte[esi]
588
	mov	ah, byte[esi + 4]
589
	add	esi, [src_width_bytes]
590
	movzx	ebx, byte[esi]
591
	movzx	ecx, byte[esi + 4]
592
	mov	esi, edx
593
	movzx	edx, ah
594
	and	eax, 0x000000ff
595
 
596
	imul	edx, esi
597
	imul	ecx, esi
598
	neg	esi
599
	add	esi, [scl_width_pixels]
600
	imul	eax, esi
601
	imul	ebx, esi
602
	add	eax, edx
603
	add	ebx, ecx
604
	mov	esi, [scl_width_pixels_inv]
605
	mul	esi
606
	mov	ecx, edx
607
	mov	eax, ebx
608
	mul	esi
609
	mov	eax, edx
610
 
611
	mov	edx, [rem_y]
612
	imul	eax, edx
613
	neg	edx
614
	add	edx, [scl_height_pixels]
615
	imul	ecx, edx
616
	add	eax, ecx
617
	mul	[scl_height_pixels_inv]
618
	mov	byte[edi], dl
619
	add	edi, 1
620
end repeat
621
 
622
	add	[dst_x], 1
623
	mov	eax, [dst_x]
624
	cmp	eax, [scl_width_pixels]
625
	jne	.bilinear.bpp32.pixel
626
 
627
	add	[dst_y], 1
628
	mov	eax, [dst_y]
629
	cmp	eax, [scl_height_pixels]
630
	jne	.bilinear.bpp32.line
631
 
632
	mov	eax, [_dst]
633
	jmp	.quit
634
 
635
 
636
  .error:
637
	xor	eax, eax
638
  .quit:
639
	ret
640
 
641
endp
642