Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1535 IgorA 1
format MS COFF
2
public EXPORTS
3
section '.flat' code readable align 16
4
 
5
include '../../../../macros.inc'
6
include '../../../../proc32.inc'
7
 
8
;-----------------------------------------------------------------------------
9
mem.alloc   dd ? ;функция для выделения памяти
10
mem.free    dd ? ;функция для освобождения памяти
11
mem.realloc dd ? ;функция для перераспределения памяти
12
dll.load    dd ?
13
 
14
BUF_STRUCT_SIZE equ 21
15
buf2d_data equ dword[edi] ;данные буфера изображения
16
buf2d_w equ dword[edi+8] ;ширина буфера
17
buf2d_h equ dword[edi+12] ;высота буфера
1538 IgorA 18
buf2d_l equ word[edi+4]
1535 IgorA 19
buf2d_t equ word[edi+6] ;отступ сверху
20
buf2d_size_lt equ dword[edi+4] ;отступ слева и справа для буфера
21
buf2d_color equ dword[edi+16] ;цвет фона буфера
22
buf2d_bits equ byte[edi+20] ;количество бит в 1-й точке изображения
23
 
24
struct buf_2d_header
25
	img_data dd ?
26
	left dw ? ;+4 left
27
	top dw ? ;+6 top
28
	size_x dd ? ;+8 w
29
	size_y dd ? ;+12 h
30
	color dd ? ;+16 color
31
	bit_pp db ? ;+21 bit in pixel
32
ends
33
 
34
macro swap v1, v2 {
35
  push v1
36
  push v2
37
  pop v1
38
  pop v2
39
}
40
 
41
;флаги, для функции обрезания буфера
42
BUF2D_OPT_CROP_TOP equ 1 ;обрезка сверху
43
BUF2D_OPT_CROP_LEFT equ 2 ;обрезка слева
44
BUF2D_OPT_CROP_BOTTOM equ 4 ;обрезка снизу
45
BUF2D_OPT_CROP_RIGHT equ 8 ;обрезка справа
46
BUF2D_BIT_OPT_CROP_TOP equ 0
47
BUF2D_BIT_OPT_CROP_LEFT equ 1
48
BUF2D_BIT_OPT_CROP_BOTTOM equ 2
49
BUF2D_BIT_OPT_CROP_RIGHT equ 3
50
 
51
;input:
52
; eax = указатель на функцию выделения памяти
53
; ebx = ... освобождения памяти
54
; ecx = ... перераспределения памяти
55
; edx = ... загрузки библиотеки (пока не используется)
56
align 16
57
lib_init:
58
	mov dword[mem.alloc], eax
59
	mov dword[mem.free], ebx
60
	mov dword[mem.realloc], ecx
61
	mov dword[dll.load], edx
62
	ret
63
 
6175 IgorA 64
include 'fun_draw.inc' ;функции рисования в буфере
1535 IgorA 65
 
66
;создание буфера
67
align 4
68
proc buf_create, buf_struc:dword
69
	pushad
70
	mov edi,dword[buf_struc]
71
	mov ecx,buf2d_w
72
	mov ebx,buf2d_h
73
	imul ecx,ebx
74
	cmp buf2d_bits,24
75
	jne @f
76
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
77
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
78
	@@:
79
	cmp buf2d_bits,32
80
	jne @f
81
		shl ecx,2 ; 32 bit = 4
82
	@@:
83
	invoke mem.alloc,ecx
84
	mov buf2d_data,eax
85
 
86
	stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
87
	popad
88
	ret
89
endp
90
 
91
;создание буфера на основе изображения rgb
92
align 4
93
proc buf_create_f_img, buf_struc:dword, rgb_data:dword
94
	pushad
95
	mov edi,dword[buf_struc]
96
	mov ecx,buf2d_w
97
	mov ebx,buf2d_h
98
	imul ecx,ebx
99
	cmp buf2d_bits,24
100
	jne @f
101
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
102
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
103
	@@:
104
	cmp buf2d_bits,32
105
	jne @f
106
		shl ecx,2 ; 32 bit = 4
107
	@@:
108
	invoke mem.alloc,ecx
109
	mov buf2d_data,eax
110
 
111
	cmp buf2d_bits,24
112
	jne @f
113
		cld
114
		mov esi,[rgb_data]
115
		mov edi,eax ;eax=buf2d_data
116
		rep movsb ;копируем биты изображения в буфер
117
		jmp .end_create
118
	@@:
119
		stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
120
	.end_create:
121
	popad
122
	ret
123
endp
124
 
1538 IgorA 125
;функция для обрезания буферов 8 и 24 битных, по заданому цвету.
126
;параметр opt задается комбинацией констант:
127
; BUF2D_OPT_CROP_TOP - обрезка сверху
128
; BUF2D_OPT_CROP_LEFT - обрезка слева
129
; BUF2D_OPT_CROP_BOTTOM - обрезка снизу
130
; BUF2D_OPT_CROP_RIGHT - обрезка справа
1535 IgorA 131
align 4
1538 IgorA 132
proc buf_crop_color, buf_struc:dword, color:dword, opt:dword
1535 IgorA 133
locals
134
	crop_r dd ?
135
endl
136
	pushad
137
	mov edi,dword[buf_struc]
138
	cmp buf2d_bits,24
139
	jne .24end_f
140
 
141
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
142
	jae .24no_crop_bottom
143
		mov eax,dword[color]
144
		mov edx,eax ;ax = colors - r,g
145
		shr edx,16 ;dl = color - b
146
		mov ecx,buf2d_h
1555 IgorA 147
		cmp ecx,1
148
		jle .24no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 149
		mov ebx,buf2d_w
150
		imul ecx,ebx
151
		lea esi,[ecx+ecx*2] ;esi=3*ecx
152
		add esi,buf2d_data
153
		cld
154
		@@:
155
			sub esi,3
156
			cmp word[esi],ax
157
			jne @f
158
			cmp byte[esi+2],dl
159
			jne @f
160
			loop @b
161
		@@:
162
		lea ebx,[ebx+ebx*2]
163
		xor edx,edx
164
		mov eax,buf2d_h
165
		imul eax,ebx
166
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
167
		@@:
168
			add esi,ebx
169
			cmp esi,eax
170
			jge @f
171
			inc edx ;вычисляем число полных строк для обрезания
172
			loop @b
173
		@@:
174
		cmp edx,0
175
		je .24no_crop_bottom
176
			cmp edx,buf2d_h
177
			jge .24no_crop_bottom ;что-бы не получить пустой буфер
178
			sub buf2d_h,edx ;уменьшаем высоту буфера
179
			mov ecx,buf2d_h
180
			imul ecx,ebx ;ecx = новый размер изображения
181
			invoke mem.realloc,buf2d_data,ecx
182
			mov buf2d_data,eax ;на случай если изменился указатель на данные
183
	.24no_crop_bottom:
184
 
185
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
186
	jae .24no_crop_top
187
		mov eax,dword[color]
188
		mov edx,eax ;ax = colors - r,g
189
		shr edx,16 ;dl = color - b
190
		mov esi,buf2d_data
191
		mov ecx,buf2d_h
1555 IgorA 192
		cmp ecx,1
193
		jle .24no_crop_top ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 194
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
195
		mov ebx,buf2d_w
196
		imul ecx,ebx
197
		cld
198
		@@:
199
			cmp word[esi],ax
200
			jne @f
201
			cmp byte[esi+2],dl
202
			jne @f
203
			add esi,3
204
			loop @b
205
		@@:
206
		lea ebx,[ebx+ebx*2]
207
		xor edx,edx
208
		@@:
209
			sub esi,ebx
210
			cmp esi,buf2d_data
211
			jl @f
212
			inc edx ;вычисляем число полных строк для обрезания
213
			loop @b
214
		@@:
215
		cmp edx,0
216
		je .24no_crop_top
217
			xor eax,eax
218
			sub eax,edx
219
			mov ebx,buf2d_h
220
			sub ebx,edx
221
			stdcall buf_offset_h, edi, eax, edx, ebx ;сдвигаем изображение в буфере вверх (eax<0)
222
			sub buf2d_h,edx ;уменьшаем высоту буфера
223
			mov ecx,buf2d_h
224
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
225
			mov ebx,buf2d_w
226
			imul ecx,ebx
227
			lea ecx,[ecx+ecx*2]
228
			invoke mem.realloc,buf2d_data,ecx
229
			mov buf2d_data,eax ;на случай если изменился указатель на данные
230
	.24no_crop_top:
231
 
232
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
233
	jae .24no_crop_right
234
		mov eax,dword[color]
235
		mov edx,eax ;ax = colors - r,g
236
		shr edx,16 ;dl = color - b
237
		mov ebx,buf2d_w
1555 IgorA 238
		cmp ebx,1
239
		jle .24no_crop_right ;на случай если ширина буфера 1 пиксель
1535 IgorA 240
		lea ebx,[ebx+ebx*2]
241
		mov esi,ebx
242
		imul esi,buf2d_h
243
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
244
		mov dword[crop_r],0
245
		cld
1538 IgorA 246
		.24found_beg_right:
1535 IgorA 247
		sub esi,3 ;двигаемся на 1-ну колонку влево
248
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
249
		@@:
250
			cmp word[esi],ax
1538 IgorA 251
			jne .24found_right
1535 IgorA 252
			cmp byte[esi+2],dl
1538 IgorA 253
			jne .24found_right
1535 IgorA 254
			sub esi,ebx ;прыгаем на верхнюю строку
255
			loop @b
256
		inc dword[crop_r]
257
 
258
		mov ecx,buf2d_w
259
		dec ecx ;1 колонка на запас
260
		cmp dword[crop_r],ecx
1538 IgorA 261
		jge .24found_right
1535 IgorA 262
 
263
		sub esi,3 ;двигаемся на 1-ну колонку влево
264
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
265
		@@:
266
			add esi,ebx ;прыгаем на нижнюю строку
267
			cmp word[esi],ax
1538 IgorA 268
			jne .24found_right
1535 IgorA 269
			cmp byte[esi+2],dl
1538 IgorA 270
			jne .24found_right
1535 IgorA 271
			loop @b
272
		inc dword[crop_r]
273
 
274
		mov ecx,buf2d_w
275
		dec ecx ;1 колонка на запас
276
		cmp dword[crop_r],ecx
1538 IgorA 277
		jl .24found_beg_right
1535 IgorA 278
 
1538 IgorA 279
		.24found_right:
1535 IgorA 280
		cmp dword[crop_r],0
281
		je .24no_crop_right
282
			mov ecx,buf2d_w
283
			sub ecx,dword[crop_r]
1538 IgorA 284
			stdcall img_rgb_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
1535 IgorA 285
			mov buf2d_w,ecx ;ставим новую ширину для буфера
286
			mov ebx,buf2d_h
287
			imul ecx,ebx
288
			lea ecx,[ecx+ecx*2]
289
			invoke mem.realloc,buf2d_data,ecx
290
			mov buf2d_data,eax ;на случай если изменился указатель на данные
291
	.24no_crop_right:
292
 
1538 IgorA 293
	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
294
	jae .24no_crop_left
295
		mov eax,dword[color]
296
		mov edx,eax ;ax = colors - r,g
297
		shr edx,16 ;dl = color - b
298
		mov ebx,buf2d_w
1555 IgorA 299
		cmp ebx,1
300
		jle .24no_crop_left ;на случай если ширина буфера 1 пиксель
1538 IgorA 301
		lea ebx,[ebx+ebx*2]
302
		mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
303
		mov dword[crop_r],0
304
		cld
305
		.24found_beg_left:
306
 
307
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
308
		@@:
309
			cmp word[esi],ax
310
			jne .24found_left
311
			cmp byte[esi+2],dl
312
			jne .24found_left
313
			add esi,ebx ;прыгаем на нижнюю строку
314
			loop @b
315
		inc dword[crop_r]
316
		add esi,3 ;двигаемся на 1-ну колонку вправо
317
 
318
		mov ecx,buf2d_w
319
		dec ecx ;1 колонка на запас
320
		cmp dword[crop_r],ecx
321
		jge .24found_left
322
 
323
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
324
		@@:
325
			sub esi,ebx ;прыгаем на верхнюю строку
326
			cmp word[esi],ax
327
			jne .24found_left
328
			cmp byte[esi+2],dl
329
			jne .24found_left
330
			loop @b
331
		inc dword[crop_r]
332
		add esi,3 ;двигаемся на 1-ну колонку вправо
333
 
334
		mov ecx,buf2d_w
335
		dec ecx ;1 колонка на запас
336
		cmp dword[crop_r],ecx
337
		jl .24found_beg_left
338
 
339
		.24found_left:
340
		cmp dword[crop_r],0
341
		je .24no_crop_left
342
			mov ecx,buf2d_w
343
			sub ecx,dword[crop_r]
344
			stdcall img_rgb_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
345
			mov buf2d_w,ecx ;ставим новую ширину для буфера
346
			mov ebx,buf2d_h
347
			imul ecx,ebx
348
			lea ecx,[ecx+ecx*2]
349
			invoke mem.realloc,buf2d_data,ecx
350
			mov buf2d_data,eax ;на случай если изменился указатель на данные
351
			mov eax,dword[crop_r]
352
			add buf2d_l,ax
353
	.24no_crop_left:
354
 
1535 IgorA 355
	.24end_f:
356
 
357
 
358
	cmp buf2d_bits,8
359
	jne .8end_f
360
 
361
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
362
	jae .8no_crop_bottom
363
		mov eax,dword[color]
364
		mov esi,buf2d_data
365
		mov ecx,buf2d_h
1555 IgorA 366
		cmp ecx,1
367
		jle .8no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 368
		mov ebx,buf2d_w
369
		imul ecx,ebx
370
		mov esi,ecx
371
		add esi,buf2d_data
372
		cld
373
		@@:
374
			dec esi
375
			cmp byte[esi],al
376
			jne @f
377
			loop @b
378
		@@:
379
		xor edx,edx
380
		mov eax,buf2d_h
381
		imul eax,ebx
382
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
383
		@@:
384
			add esi,ebx
385
			cmp esi,eax
386
			jge @f
387
			inc edx
388
			loop @b
389
		@@:
390
		cmp edx,0
391
		je .8no_crop_bottom
392
			cmp edx,buf2d_h
393
			jge .8no_crop_bottom ;что-бы не получить пустой буфер
394
			sub buf2d_h,edx ;уменьшаем высоту буфера
395
			mov ecx,buf2d_h
396
			imul ecx,ebx ;ecx = новый размер изображения
397
			invoke mem.realloc,buf2d_data,ecx
398
			mov buf2d_data,eax ;на случай если изменился указатель на данные
399
	.8no_crop_bottom:
400
 
401
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
402
	jae .8no_crop_top
403
		mov eax,dword[color]
404
		mov esi,buf2d_data
405
		mov ecx,buf2d_h
1555 IgorA 406
		cmp ecx,1
407
		jle .8no_crop_top ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 408
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
409
		mov ebx,buf2d_w
410
		imul ecx,ebx
411
		cld
412
		@@:
413
			cmp byte[esi],al
414
			jne @f
415
			inc esi
416
			loop @b
417
		@@:
418
		xor edx,edx
419
		@@:
420
			sub esi,ebx
421
			cmp esi,buf2d_data
422
			jl @f
423
			inc edx
424
			loop @b
425
		@@:
426
		cmp edx,0
427
		je .8no_crop_top
428
			xor eax,eax
429
			sub eax,edx
430
			mov ebx,buf2d_h
431
			sub ebx,edx
432
			stdcall buf_offset_h, edi, eax, edx, ebx
433
			mov ecx,buf2d_h
434
			sub ecx,edx
435
			mov buf2d_h,ecx ;уменьшаем высоту буфера
436
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
437
			mov ebx,buf2d_w
438
			imul ecx,ebx
439
			invoke mem.realloc,buf2d_data,ecx
440
			mov buf2d_data,eax ;на случай если изменился указатель на данные
441
	.8no_crop_top:
442
 
443
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
444
	jae .8no_crop_right
445
		mov eax,dword[color]
446
		mov ebx,buf2d_w
1555 IgorA 447
		cmp ebx,1
448
		jle .8no_crop_right ;на случай если ширина буфера 1 пиксель
1535 IgorA 449
		mov esi,ebx
450
		imul esi,buf2d_h
451
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
452
		xor edx,edx
453
		cld
454
 
455
		.8found_beg:
456
		dec esi ;двигаемся на 1-ну колонку влево
457
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
458
		@@:
459
			cmp byte[esi],al
460
			jne .8found
461
			sub esi,ebx ;прыгаем на верхнюю строку
462
			loop @b
463
		inc edx
464
		mov ecx,buf2d_w
465
		dec ecx ;1 колонка на запас
466
		cmp edx,ecx
467
		jge .8found
468
 
469
		dec esi ;двигаемся на 1-ну колонку влево
470
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
471
		@@:
472
			add esi,ebx ;прыгаем на нижнюю строку
473
			cmp byte[esi],al
474
			jne .8found
475
			loop @b
476
		inc edx
477
 
478
		mov ecx,buf2d_w
479
		dec ecx ;1 колонка на запас
480
		cmp edx,ecx
481
		jl .8found_beg
482
 
483
		.8found:
484
		cmp edx,0
485
		je .8no_crop_right
486
			mov ecx,buf2d_w
487
			sub ecx,edx
1538 IgorA 488
			stdcall img_gray_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
1535 IgorA 489
			mov buf2d_w,ecx ;ставим новую ширину для буфера
490
			mov ebx,buf2d_h
491
			imul ecx,ebx
492
			invoke mem.realloc,buf2d_data,ecx
493
			mov buf2d_data,eax ;на случай если изменился указатель на данные
494
	.8no_crop_right:
495
 
1538 IgorA 496
	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
497
	jae .8no_crop_left
498
		mov eax,dword[color]
499
		mov ebx,buf2d_w
1555 IgorA 500
		cmp ebx,1
501
		jle .8no_crop_left ;на случай если ширина буфера 1 пиксель
1538 IgorA 502
		mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
503
		mov edx,0
504
		cld
505
		.8found_beg_left:
506
 
507
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
508
		@@:
509
			cmp word[esi],ax
510
			jne .8found_left
511
			add esi,ebx ;прыгаем на нижнюю строку
512
			loop @b
513
		inc edx
514
		inc esi ;двигаемся на 1-ну колонку вправо
515
 
516
		mov ecx,buf2d_w
517
		dec ecx ;1 колонка на запас
518
		cmp edx,ecx
519
		jge .8found_left
520
 
521
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
522
		@@:
523
			sub esi,ebx ;прыгаем на верхнюю строку
524
			cmp word[esi],ax
525
			jne .8found_left
526
			loop @b
527
		inc edx
528
		inc esi ;двигаемся на 1-ну колонку вправо
529
 
530
		mov ecx,buf2d_w
531
		dec ecx ;1 колонка на запас
532
		cmp edx,ecx
533
		jl .8found_beg_left
534
 
535
		.8found_left:
536
		cmp edx,0
537
		je .8no_crop_left
538
			mov ecx,buf2d_w
539
			sub ecx,edx
540
			stdcall img_gray_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
541
			mov buf2d_w,ecx ;ставим новую ширину для буфера
542
			mov ebx,buf2d_h
543
			imul ecx,ebx
544
			invoke mem.realloc,buf2d_data,ecx
545
			mov buf2d_data,eax ;на случай если изменился указатель на данные
546
			mov eax,edx
547
			add buf2d_l,ax
548
	.8no_crop_left:
549
 
1535 IgorA 550
	.8end_f:
551
 
552
	popad
553
	ret
554
endp
555
 
1538 IgorA 556
;обрезаем цветное изображение с правой стороны
1535 IgorA 557
;input:
558
;data_rgb - pointer to rgb data
559
;size_w_old - width img in pixels
560
;size_w_new - new width img in pixels
561
;size_h - height img in pixels
562
align 4
1538 IgorA 563
proc img_rgb_crop_r, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
1535 IgorA 564
	pushad
565
	mov eax, dword[size_w_old]
566
	lea eax, dword[eax+eax*2] ;eax = width(old) * 3(rgb)
567
	mov ebx, dword[size_w_new]
568
	lea ebx, dword[ebx+ebx*2] ;ebx = width(new) * 3(rgb)
569
	mov edx, dword[size_h]
570
	mov edi, dword[data_rgb] ;edi - получает данные
571
	mov esi, edi
572
	add edi, ebx
573
	add esi, eax
574
	cld
575
	@@:
576
		dec edx ;уменьшаем счетчик оставшихся строк на 1
577
		cmp edx,0
578
		jle @f
579
		mov ecx, ebx
580
		rep movsb ;перенос (копирование) строки пикселей
581
		add esi,eax ;переход на новую строчку изображения
582
		sub esi,ebx
583
		jmp @b
584
	@@:
585
	popad
586
	ret
587
endp
588
 
1538 IgorA 589
;обрезаем серое изображение с правой стороны
1535 IgorA 590
;input:
591
;data_gray - pointer to gray data
592
;size_w_old - width img in pixels
593
;size_w_new - new width img in pixels
594
;size_h - height img in pixels
595
align 4
1538 IgorA 596
proc img_gray_crop_r, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
1535 IgorA 597
	pushad
598
	mov eax, dword[size_w_old]
599
	mov ebx, dword[size_w_new]
600
	mov edx, dword[size_h]
601
	mov edi, dword[data_gray] ;edi - получает данные
602
	mov esi, edi
603
	add edi, ebx
604
	add esi, eax
605
	cld
606
	@@:
607
		dec edx ;уменьшаем счетчик оставшихся строк на 1
608
		cmp edx,0
609
		jle @f
610
		mov ecx, ebx
611
		rep movsb ;перенос (копирование) строки пикселей
612
		add esi,eax ;переход на новую строчку изображения
613
		sub esi,ebx
614
		jmp @b
615
	@@:
616
	popad
617
	ret
618
endp
619
 
1538 IgorA 620
;обрезаем цветное изображение с левой стороны
621
;input:
622
;data_rgb - pointer to rgb data
623
;size_w_old - width img in pixels
624
;size_w_new - new width img in pixels
625
;size_h - height img in pixels
626
align 4
627
proc img_rgb_crop_l, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
628
	pushad
629
	mov edi,dword[data_rgb]
630
	mov esi,edi
631
	mov eax,dword[size_w_old]
632
	mov ebx,dword[size_w_new]
633
	cmp eax,ebx
634
	jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
635
		lea eax,[eax+eax*2]
636
		lea ebx,[ebx+ebx*2]
637
		sub eax,ebx
638
		mov edx,dword[size_h] ;высота изображения
639
		cld
640
		@@:
641
			add esi,eax
642
			mov ecx,ebx
643
			rep movsb
644
			dec edx
645
			cmp edx,0
646
			jg @b
647
	.end_f:
648
	popad
649
	ret
650
endp
651
 
652
;обрезаем серое изображение с левой стороны
653
;input:
654
;data_gray - pointer to gray data
655
;size_w_old - width img in pixels
656
;size_w_new - new width img in pixels
657
;size_h - height img in pixels
658
align 4
659
proc img_gray_crop_l, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
660
	pushad
661
	mov edi,dword[data_gray]
662
	mov esi,edi
663
	mov eax,dword[size_w_old]
664
	mov ebx,dword[size_w_new]
665
	cmp eax,ebx
666
	jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
667
		sub eax,ebx
668
		mov edx,dword[size_h] ;высота изображения
669
		cld
670
		@@:
671
			add esi,eax
672
			mov ecx,ebx
673
			rep movsb
674
			dec edx
675
			cmp edx,0
676
			jg @b
677
	.end_f:
678
	popad
679
	ret
680
endp
681
 
1535 IgorA 682
;hoffs - колличество пикселей на котрые поднимается/опускается изображение
683
;img_t - высота, с которой начинается двигающаяся часть изображения
684
align 4
685
proc buf_offset_h, buf_struc:dword, hoffs:dword, img_t:dword, img_h:dword ;сдвигает изображение по высоте
686
	pushad
687
	mov edi,dword[buf_struc]
688
	cmp buf2d_bits,24
689
	jne .end_move_24
690
 
691
	mov eax,[hoffs]
692
	cmp eax,0
693
	je .end_move_24
694
		mov ebx,buf2d_w
695
		mov edx,dword[img_t]
696
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
697
			cmp ecx,buf2d_h
698
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
699
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
700
			lea ecx,[ecx+ecx*2]
701
		imul ebx,edx
702
		lea ebx,[ebx+ebx*2]
703
		mov esi,buf2d_data
704
		add esi,ebx
705
 
706
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
707
		mov ebx,buf2d_w
708
		imul ebx,edx
709
		lea ebx,[ebx+ebx*2]
710
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
711
		add edi,ebx
712
 
713
		cmp eax,0
714
		jg .move_down_24
715
			;двигаем изображение вверх
716
			cld
717
			rep movsb
718
			jmp .end_f
719
		.move_down_24:
720
			;двигаем изображение вниз
721
			add esi,ecx
722
			dec esi
723
			add edi,ecx
724
			dec edi
725
			std
726
			rep movsb
727
			jmp .end_f
728
	.end_move_24:
729
 
730
;stdcall print_err,sz_buf2d_offset_h,txt_err_n24b
731
 
732
	cmp buf2d_bits,8
733
	jne .end_move_8
734
 
735
	mov eax,[hoffs]
736
	cmp eax,0
737
	je .end_move_8
738
		;двигаем изображение вверх
739
		mov ebx,buf2d_w
740
		mov edx,dword[img_t]
741
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
742
			cmp ecx,buf2d_h
743
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
744
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
745
		imul ebx,edx
746
		mov esi,buf2d_data
747
		add esi,ebx
748
 
749
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
750
		mov ebx,buf2d_w
751
		imul ebx,edx
752
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
753
		add edi,ebx
754
 
755
		cmp eax,0
756
		jg .move_down_8
757
			cld
758
			rep movsb
759
			jmp .end_f
760
		.move_down_8:
761
			;двигаем изображение вниз
762
			add esi,ecx
763
			dec esi
764
			add edi,ecx
765
			dec edi
766
			std
767
			rep movsb
768
			jmp .end_f
769
	.end_move_8:
770
 
771
	.end_f:
772
	popad
773
	ret
774
endp
775
 
776
align 4
777
proc buf_delete, buf_struc:dword
2136 IgorA 778
	push eax edi
1535 IgorA 779
	mov edi,dword[buf_struc]
780
	invoke mem.free,buf2d_data
2136 IgorA 781
	pop edi eax
1535 IgorA 782
	ret
783
endp
784
 
6175 IgorA 785
;input:
786
; new_w - новая ширина (если 0 то не меняется)
787
; new_h - новая высота (если 0 то не меняется)
788
; options - параметры изменения буфера (1 - изменять размер буфера,
789
;    2 - изменять изображение в буфере, 3 - изменять буфер и изображение)
1535 IgorA 790
align 4
6175 IgorA 791
proc buf_resize, buf_struc:dword, new_w:dword, new_h:dword, options:dword
2136 IgorA 792
	pushad
793
	mov edi,dword[buf_struc]
6175 IgorA 794
	cmp buf2d_bits,8
795
	jne .8bit
796
		bt dword[options],1 ;сжатие изобр.
797
		jnc @f
798
			;...
799
		@@:
800
		bt dword[options],0 ;измен. буфер
801
		jnc .end_f
802
			;...
803
		jmp .end_f
804
	.8bit:
2136 IgorA 805
	cmp buf2d_bits,24
806
	jne .24bit
6175 IgorA 807
		bt dword[options],1 ;сжатие изобр.
808
		jnc .24_end_r
809
			mov eax,dword[new_w]
810
			cmp eax,1
811
			jl @f
812
			cmp eax,buf2d_w
813
			jge @f
814
				;сжатие по ширине
815
				stdcall img_rgb24_wresize, buf2d_data,buf2d_w,buf2d_h,eax
816
				jmp .24_r_h
817
			@@:
818
			mov eax,buf2d_w
819
			.24_r_h: ;eax - ширина буфера или ширина сжатого изображения
820
			mov ebx,dword[new_h]
821
			cmp ebx,1
822
			jl @f
823
			cmp ebx,buf2d_h
824
			jge @f
825
				;сжатие по высоте
826
				;... еще не поддерживается ...
827
			@@:
828
		.24_end_r:
829
		bt dword[options],0 ;измен. буфер
830
		jnc .end_f
2136 IgorA 831
		mov eax,dword[new_w]
832
		cmp eax,1
833
		jl @f
834
			mov buf2d_w,eax
835
		@@:
836
		mov ecx,buf2d_w
837
		mov eax,dword[new_h]
838
		cmp eax,1
839
		jl @f
840
			mov buf2d_h,eax
841
		@@:
842
		mov ebx,buf2d_h
843
		imul ecx,ebx
844
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
845
		invoke mem.realloc,buf2d_data,ecx ;изменяем память занимаемую буфером
846
		mov buf2d_data,eax ;на случай если изменился указатель на данные
847
	.24bit:
6175 IgorA 848
	.end_f:
2136 IgorA 849
	popad
850
	ret
851
endp
852
 
853
align 4
2975 IgorA 854
rot_table: ;таблица для указания на подфункции для поворотов
855
	dd buf_rotate.8b90,buf_rotate.24b90,buf_rotate.32b90,\
856
	buf_rotate.8b180,buf_rotate.24b180,buf_rotate.32b180
857
 
858
;поворот изображения на 90 или 180 градусов
859
align 4
860
proc buf_rotate, buf_struc:dword, angle:dword
861
locals
862
	n_data dd ?
863
	dec_h dd ? ;число байт, для уменьшения координаты y
864
endl
865
	pushad
866
	mov edi,[buf_struc]
867
	mov ebx,buf2d_w
868
	mov ecx,buf2d_h
869
 
870
	lea eax,[rot_table]
871
	cmp dword[angle],90 ;проверка угла поворота
872
	je .beg_0
873
	cmp dword[angle],180
874
	jne @f
875
		add eax,12
876
		jmp .beg_0
877
	@@:
878
	jmp .end_f
879
	.beg_0: ;проверка битности буфера
880
	cmp buf2d_bits,8
881
	jne @f
882
		jmp dword[eax]
883
	@@:
884
	cmp buf2d_bits,24
885
	jne @f
886
		add eax,4
887
		jmp dword[eax]
888
	@@:
889
	cmp buf2d_bits,32
890
	jne @f
891
		add eax,8
892
		jmp dword[eax]
893
	@@:
894
	jmp .end_f
895
 
896
	.8b90: ;поворот 8 битного буфера на 90 градусов
897
		mov edx,ecx ;edx - buf_h
898
		imul ecx,ebx
899
		invoke mem.alloc,ecx ;выделяем временную память
900
		cmp eax,0
901
		je .end_f
902
		mov [n_data],eax
903
		mov [dec_h],ecx
904
		inc dword[dec_h]
905
 
906
		;copy buf --> mem
907
		mov edi,[buf_struc]
908
		mov esi,buf2d_data
909
		mov edi,eax ;[n_data]
910
		dec edx ;коректируем edx на 1 байт, для компенсации сдвига в movsb
911
		add edi,edx
912
		xor eax,eax
913
		cld
914
		.cycle_0:
915
			movsb
916
			add edi,edx
917
			inc eax
918
			cmp eax,ebx
919
			jl @f
920
				xor eax,eax
921
				sub edi,[dec_h]
922
			@@:
923
			loop .cycle_0
924
 
925
		;change buf_w <---> buf_h
926
		mov esi,[n_data]
927
		mov edi,[buf_struc]
928
		mov edi,buf2d_data
929
		mov ecx,ebx
930
		inc edx ;исправляем скоректированный edx
931
		imul ecx,edx
932
		;copy buf <-- mem
933
		;cld
934
		rep movsb
935
		invoke mem.free,[n_data]
936
		jmp .change_w_h
937
	.24b90: ;поворот 24 битного буфера на 90 градусов
938
		mov esi,ecx
939
		imul esi,ebx
940
		lea ecx,[ecx+ecx*2]
941
		mov edx,ecx ;edx - buf_h * 3
942
		imul ecx,ebx
943
		invoke mem.alloc,ecx ;выделяем временную память
944
		cmp eax,0
945
		je .end_f
946
		mov [n_data],eax
947
		mov [dec_h],ecx
948
		add dword[dec_h],3
949
 
950
		;copy buf --> mem
951
 
952
		mov edi,[buf_struc]
953
		mov ecx,esi
954
		mov esi,buf2d_data
955
		mov edi,eax ;[n_data]
956
		sub edx,3 ;коректируем edx на 3 байта, для компенсации сдвига
957
		add edi,edx
958
		xor eax,eax
959
		cld
960
		.cycle_1:
961
			movsw
962
			movsb
963
			add edi,edx
964
			inc eax
965
			cmp eax,ebx
966
			jl @f
967
				xor eax,eax
968
				sub edi,[dec_h]
969
			@@:
970
			loop .cycle_1
971
 
972
		;copy buf <-- mem
973
		mov esi,[n_data]
974
		mov edi,[buf_struc]
975
		mov edi,buf2d_data
976
		mov ecx,ebx
977
		add edx,3 ;исправляем скоректированный edx
978
		imul ecx,edx
979
		;cld
980
		rep movsb
981
		invoke mem.free,[n_data]
982
		jmp .change_w_h
983
	.32b90: ;поворот 32 битного буфера на 90 градусов
984
		shl ecx,2
985
		mov edx,ecx ;edx - buf_h * 4
986
		imul ecx,ebx
987
		invoke mem.alloc,ecx ;выделяем временную память
988
		cmp eax,0
989
		je .end_f
990
		mov [n_data],eax
991
		mov [dec_h],ecx
992
		add dword[dec_h],4
993
 
994
		;copy buf --> mem
995
		mov edi,[buf_struc]
996
		shr ecx,2
997
		mov esi,buf2d_data
998
		mov edi,eax ;[n_data]
999
		sub edx,4 ;коректируем edx на 4 байта, для компенсации сдвига в movsd
1000
		add edi,edx
1001
		xor eax,eax
1002
		cld
1003
		.cycle_2:
1004
			movsd
1005
			add edi,edx
1006
			inc eax
1007
			cmp eax,ebx
1008
			jl @f
1009
				xor eax,eax
1010
				sub edi,[dec_h]
1011
			@@:
1012
			loop .cycle_2
1013
 
1014
		;copy buf <-- mem
1015
		mov esi,[n_data]
1016
		mov edi,[buf_struc]
1017
		mov edi,buf2d_data
1018
		mov ecx,ebx
1019
		add edx,4 ;исправляем скоректированный edx
1020
		imul ecx,edx
1021
		shr ecx,2
1022
		;cld
1023
		rep movsd
1024
		invoke mem.free,[n_data]
1025
		;jmp .change_w_h
1026
	.change_w_h: ;change buf_w <---> buf_h
1027
		mov edi,[buf_struc]
1028
		mov eax,buf2d_w
1029
		mov ebx,buf2d_h
1030
		mov buf2d_h,eax
1031
		mov buf2d_w,ebx
1032
		jmp .end_f
1033
	.8b180: ;поворот 8 битного буфера на 180 градусов
1034
		mov edi,buf2d_data
1035
		mov esi,edi
1036
		imul ecx,ebx
1037
		add esi,ecx
1038
		dec esi
1039
		shr ecx,1 ;ecx - число пикселей буфера : 2
1040
		std
1041
		@@:
1042
			lodsb
1043
			mov ah,byte[edi]
1044
			mov byte[esi+1],ah
1045
			mov byte[edi],al
1046
			inc edi
1047
			loop @b
1048
			jmp .end_f
1049
	.24b180: ;поворот 24 битного буфера на 180 градусов
1050
		mov esi,buf2d_data
1051
		mov edi,esi
1052
		imul ecx,ebx
1053
		mov eax,ecx
1054
		lea ecx,[ecx+ecx*2]
1055
		add edi,ecx
1056
		sub edi,3
1057
		shr eax,1
1058
		mov ecx,eax ;ecx - число пикселей буфера : 2
1059
		cld
1060
		@@:
1061
			lodsw
1062
			mov edx,eax
1063
			lodsb
1064
			mov bx,word[edi]
1065
			mov word[esi-3],bx
1066
			mov bl,byte[edi+2]
1067
			mov byte[esi-1],bl
1068
			mov byte[edi+2],al
1069
			mov word[edi],dx
1070
			sub edi,3
1071
			loop @b
1072
			jmp .end_f
1073
	.32b180: ;поворот 32 битного буфера на 180 градусов
1074
		mov edi,buf2d_data
1075
		mov esi,edi
1076
		imul ecx,ebx
1077
		shl ecx,2
1078
		add esi,ecx
1079
		sub esi,4
1080
		shr ecx,3 ;ecx - число пикселей буфера : 2
1081
		std
1082
		@@:
1083
			lodsd
1084
			mov ebx,dword[edi]
1085
			mov dword[esi+4],ebx
1086
			mov dword[edi],eax
1087
			add edi,4
1088
			loop @b
1089
		;jmp .end_f
1090
 
1091
	.end_f:
1092
	popad
1093
	ret
1094
endp
1095
 
1096
align 4
5389 IgorA 1097
proc buf_flip_h, buf_struc:dword
1098
pushad
1099
	mov edi,[buf_struc]
1100
	cmp buf2d_bits,24
1101
	jne .end_24
1102
		mov esi,buf2d_data
1103
		mov eax,buf2d_w
1104
		mov ecx,eax
1105
		shr ecx,1
1106
		dec eax
1107
		lea eax,[eax+eax*2]
1108
		mov ebx,buf2d_h
1109
		mov edi,esi
1110
		add esi,eax
1111
		add eax,3
1112
		cld
1113
		.cycle_24:
1114
		push ecx edi esi
1115
align 4
1116
		@@:
1117
			;swap word[edi] <-> word[esi]
1118
			mov dx,[edi]
1119
			movsw
1120
			mov [esi-2],dx
1121
			;swap byte[edi] <-> byte[esi]
1122
			mov dl,[edi]
1123
			movsb
1124
			mov [esi-1],dl
1125
			sub esi,6
1126
		loop @b
1127
		pop esi edi ecx
1128
		add edi,eax
1129
		add esi,eax
1130
		dec ebx
1131
		or ebx,ebx
1132
		jnz .cycle_24
1133
		jmp .end_32
1134
	.end_24:
1135
	cmp buf2d_bits,32
1136
	jne .end_32
1137
		mov esi,buf2d_data
1138
		mov eax,buf2d_w
1139
		dec eax
1140
		shl eax,2
1141
		mov ebx,buf2d_h
1142
		mov edi,esi
1143
		add esi,eax
1144
		add eax,4
1145
		cld
1146
		.cycle_32:
1147
		mov ecx,eax
1148
		shr ecx,3
1149
		push edi esi
1150
align 4
1151
		@@:
1152
			;swap dword[edi] <-> dword[esi]
1153
			mov edx,[edi]
1154
			movsd
1155
			mov [esi-4],edx
1156
			sub esi,8
1157
		loop @b
1158
		pop esi edi
1159
		add edi,eax
1160
		add esi,eax
1161
		dec ebx
1162
		or ebx,ebx
1163
		jnz .cycle_32
1164
	.end_32:
1165
popad
1166
	ret
1167
endp
1168
 
3040 IgorA 1169
;отразить по вертикали (верх и низ меняются местами)
2658 IgorA 1170
align 4
3040 IgorA 1171
proc buf_flip_v, buf_struc:dword
1172
locals
5389 IgorA 1173
	line_pix dd ? ;кол. пикселей в линии буфера
1174
	line_2byte dd ? ;кол. байт в линии буфера * 2
3040 IgorA 1175
endl
1176
	pushad
1177
	mov edi,[buf_struc]
5389 IgorA 1178
	cmp buf2d_bits,24
1179
	jne .end_24
1180
		mov edx,buf2d_w
1181
		mov [line_pix],edx
1182
		mov ebx,buf2d_h
1183
		lea edx,[edx+edx*2]
1184
		mov esi,edx
1185
		imul esi,ebx
1186
		sub esi,edx
1187
		add esi,buf2d_data ;указатель на нижнюю линию
1188
		shr ebx,1 ;кол. линейных циклов
1189
		shl edx,1
1190
		mov [line_2byte],edx
1191
		mov edi,buf2d_data
1192
		xchg edi,esi
1193
		cld
1194
		.flip_24:
1195
		cmp ebx,0
1196
		jle .end_32 ;здесь выход из функции (потому .end_24 не подходит)
1197
		mov ecx,[line_pix]
1198
align 4
1199
		@@:
1200
			lodsw
1201
			mov dx,word[edi]
1202
			mov word[esi-2],dx
1203
			stosw
1204
			lodsb
1205
			mov ah,byte[edi]
1206
			mov byte[esi-1],ah
1207
			stosb
1208
			loop @b
1209
		sub edi,[line_2byte]
1210
		dec ebx
1211
		jmp .flip_24
1212
	.end_24:
1213
	cmp buf2d_bits,32
1214
	jne .end_32
1215
		mov edx,buf2d_w
1216
		mov [line_pix],edx
1217
		mov ebx,buf2d_h
1218
		shl edx,2
1219
		mov esi,edx
1220
		imul esi,ebx
1221
		sub esi,edx
1222
		add esi,buf2d_data ;указатель на нижнюю линию
1223
		shr ebx,1 ;кол. линейных циклов
1224
		shl edx,1
1225
		mov [line_2byte],edx
1226
		mov edi,buf2d_data
1227
		xchg edi,esi
1228
		cld
1229
		.flip_32:
1230
		cmp ebx,0
1231
		jle .end_32
1232
		mov ecx,[line_pix]
1233
align 4
1234
		@@:
1235
			lodsd
1236
			mov edx,dword[edi]
1237
			mov dword[esi-4],edx
1238
			stosd
1239
			loop @b
1240
		sub edi,[line_2byte]
1241
		dec ebx
1242
		jmp .flip_32
1243
	.end_32:
1244
	popad
1245
	ret
3040 IgorA 1246
endp
1247
 
6175 IgorA 1248
;description:
1249
; сжатие изображения по ширине в 2 раза (размеры буфера не меняются)
3040 IgorA 1250
align 4
1535 IgorA 1251
proc buf_img_wdiv2, buf_struc:dword
1252
	pushad
1253
	mov edi,dword[buf_struc]
2927 IgorA 1254
	cmp buf2d_bits,8
1255
	jne @f
1256
		mov eax,buf2d_w
1257
		mov ecx,buf2d_h
1258
		imul ecx,eax
1259
		stdcall img_8b_wdiv2, buf2d_data,ecx
1260
	@@:
1535 IgorA 1261
	cmp buf2d_bits,24
2927 IgorA 1262
	jne @f
1535 IgorA 1263
		mov eax,buf2d_w
1264
		mov ecx,buf2d_h
1265
		imul ecx,eax
1266
		stdcall img_rgb24_wdiv2, buf2d_data,ecx
2927 IgorA 1267
	@@:
2920 IgorA 1268
	cmp buf2d_bits,32
2927 IgorA 1269
	jne @f
2920 IgorA 1270
		mov eax,buf2d_w
1271
		mov ecx,buf2d_h
1272
		imul ecx,eax
2927 IgorA 1273
		stdcall img_rgba32_wdiv2, buf2d_data,ecx
1274
	@@:
1535 IgorA 1275
	popad
1276
	ret
1277
endp
1278
 
1279
;input:
2927 IgorA 1280
;data_8b - pointer to rgb data
1281
;size - count img pixels (size img data / 3(rgb) )
1282
align 4
1283
proc img_8b_wdiv2 data_8b:dword, size:dword
1284
	mov eax,dword[data_8b]
1285
	mov ecx,dword[size] ;ecx = size
1286
	cld
1287
	@@: ;затемнение цвета пикселей
1288
		shr byte[eax],1
1289
		inc eax
1290
		loop @b
1291
 
1292
	mov eax,dword[data_8b]
1293
	mov ecx,dword[size] ;ecx = size
1294
	shr ecx,1
1295
	@@: ;сложение цветов пикселей
1296
		mov bl,byte[eax+1] ;копируем цвет соседнего пикселя
1297
		add byte[eax],bl
1298
		add eax,2
1299
		loop @b
1300
 
1301
	mov eax,dword[data_8b]
1302
	inc eax
1303
	mov ebx,eax
1304
	inc ebx
1305
	mov ecx,dword[size] ;ecx = size
1306
	shr ecx,1
1307
	dec ecx ;лишний пиксель
1308
	@@: ;поджатие пикселей
1309
		mov dl,byte[ebx]
1310
		mov byte[eax],dl
1311
 
1312
		inc eax
1313
		add ebx,2
1314
		loop @b
1315
	ret
1316
endp
1317
 
1318
;input:
1535 IgorA 1319
;data_rgb - pointer to rgb data
1320
;size - count img pixels (size img data / 3(rgb) )
1321
align 4
1322
proc img_rgb24_wdiv2 data_rgb:dword, size:dword
1323
  mov eax,dword[data_rgb]
1324
  mov ecx,dword[size] ;ecx = size
1325
  lea ecx,[ecx+ecx*2]
1326
  cld
1327
  @@: ;затемнение цвета пикселей
1538 IgorA 1328
		shr byte[eax],1
1329
		inc eax
1330
		loop @b
1535 IgorA 1331
 
1332
  mov eax,dword[data_rgb]
1333
  mov ecx,dword[size] ;ecx = size
1334
  shr ecx,1
1335
  @@: ;сложение цветов пикселей
1538 IgorA 1336
		mov bx,word[eax+3] ;копируем цвет соседнего пикселя
1337
		add word[eax],bx
1338
		mov bl,byte[eax+5] ;копируем цвет соседнего пикселя
1339
		add byte[eax+2],bl
1340
		add eax,6 ;=2*3
1341
		loop @b
1535 IgorA 1342
 
1343
  mov eax,dword[data_rgb]
1344
  add eax,3
1345
  mov ebx,eax
1346
  add ebx,3
1347
  mov ecx,dword[size] ;ecx = size
1348
  shr ecx,1
1349
  dec ecx ;лишний пиксель
1350
  @@: ;поджатие пикселей
1538 IgorA 1351
		mov edx,dword[ebx]
1352
		mov word[eax],dx
1353
		shr edx,16
1354
		mov byte[eax+2],dl
1535 IgorA 1355
 
1538 IgorA 1356
		add eax,3
1357
		add ebx,6
1358
		loop @b
1535 IgorA 1359
  ret
1360
endp
1361
 
2920 IgorA 1362
;input:
2927 IgorA 1363
;data_rgba - pointer to rgba data
1364
;size - count img pixels (size img data / 4(rgba) )
1535 IgorA 1365
align 4
2927 IgorA 1366
proc img_rgba32_wdiv2 data_rgba:dword, size:dword
1367
	mov eax,dword[data_rgba]
2920 IgorA 1368
 
2927 IgorA 1369
	mov eax,dword[data_rgba]
2920 IgorA 1370
	mov ebx,eax
1371
	add ebx,4
1372
	mov ecx,dword[size] ;ecx = size
1373
	shr ecx,1
1374
	@@: ;смешивание цветов пикселей
1375
		call combine_colors_1
1376
		mov [eax],edx
1377
		add eax,8 ;=2*4
1378
		add ebx,8
1379
		loop @b
1380
 
2927 IgorA 1381
	mov eax,dword[data_rgba]
2920 IgorA 1382
	add eax,4
1383
	mov ebx,eax
1384
	add ebx,4
1385
	mov ecx,dword[size] ;ecx = size
1386
	shr ecx,1
1387
	dec ecx ;лишний пиксель
1388
	@@: ;поджатие пикселей
1389
		mov edx,dword[ebx]
1390
		mov dword[eax],edx
1391
 
1392
		add eax,4
1393
		add ebx,8
1394
		loop @b
1395
	ret
1396
endp
1397
 
3040 IgorA 1398
;description:
6175 IgorA 1399
; сжатие изображения по высоте в 2 раза (высота буфера не меняется)
2920 IgorA 1400
align 4
1535 IgorA 1401
proc buf_img_hdiv2, buf_struc:dword
1402
	pushad
1403
	mov edi,dword[buf_struc]
2927 IgorA 1404
	cmp buf2d_bits,8
1405
	jne @f
1406
		mov eax,buf2d_w
1407
		mov ecx,buf2d_h
1408
		imul ecx,eax
1409
		stdcall img_8b_hdiv2, buf2d_data,ecx,eax
3040 IgorA 1410
		jmp .end_f ;edi портится в функции, потому использование buf2d_bits опасно
2927 IgorA 1411
	@@:
1535 IgorA 1412
	cmp buf2d_bits,24
2927 IgorA 1413
	jne @f
1535 IgorA 1414
		mov eax,buf2d_w
1415
		mov ecx,buf2d_h
1416
		imul ecx,eax
1417
		stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
3040 IgorA 1418
		jmp .end_f
2927 IgorA 1419
	@@:
2920 IgorA 1420
	cmp buf2d_bits,32
2927 IgorA 1421
	jne @f
2920 IgorA 1422
		mov eax,buf2d_w
1423
		mov ecx,buf2d_h
1424
		imul ecx,eax
1425
		shl eax,2
2927 IgorA 1426
		stdcall img_rgba32_hdiv2, buf2d_data,ecx,eax
3040 IgorA 1427
		;jmp .end_f
2927 IgorA 1428
	@@:
3040 IgorA 1429
	.end_f:
1535 IgorA 1430
	popad
1431
	ret
1432
endp
1433
 
1434
;input:
2927 IgorA 1435
;data_8b - pointer to 8 bit data
1436
;size - count img pixels (size img data)
1437
;size_w - width img in pixels
1438
align 4
1439
proc img_8b_hdiv2, data_8b:dword, size:dword, size_w:dword
1440
 
1441
	mov eax,dword[data_8b] ;eax =
1442
	mov ecx,dword[size]
1443
	cld
1444
	@@: ;затемнение цвета пикселей
1445
		shr byte[eax],1
1446
		inc eax
1447
		loop @b
1448
 
1449
	mov eax,dword[data_8b] ;eax =
1450
	mov esi,dword[size_w]
1451
	mov ebx,esi
1452
	add ebx,eax
1453
	mov ecx,dword[size]  ;ecx = size
1454
	shr ecx,1
1455
	xor edi,edi
1456
	@@: ;сложение цветов пикселей
1457
		mov dl,byte[ebx] ;копируем цвет нижнего пикселя
1458
		add byte[eax],dl
1459
 
1460
		inc eax
1461
		inc ebx
1462
		inc edi
1463
		cmp edi,dword[size_w]
1464
		jl .old_line
1465
			add eax,esi
1466
			add ebx,esi
1467
			xor edi,edi
1468
		.old_line:
1469
		loop @b
1470
 
1471
 
1472
	mov eax,dword[data_8b] ;eax =
1473
	add eax,esi ;esi = width*3(rgb)
1474
	mov ebx,eax
1475
	add ebx,esi
1476
	mov ecx,dword[size] ;ecx = size
1477
	shr ecx,1
1478
	sub ecx,dword[size_w] ;лишняя строка пикселей
1479
	xor edi,edi
1480
	@@: ;поджатие пикселей
1481
		mov dl,byte[ebx] ;копируем цвет нижнего пикселя
1482
		mov byte[eax],dl
1483
 
1484
		inc eax
1485
		inc ebx
1486
		inc edi
1487
		cmp edi,dword[size_w]
1488
		jl .old_line_2
1489
			add ebx,esi
1490
			xor edi,edi
1491
		.old_line_2:
1492
		loop @b
1493
	ret
1494
endp
1495
 
1496
;input:
1535 IgorA 1497
;data_rgb - pointer to rgb data
1498
;size - count img pixels (size img data / 3(rgb) )
1499
;size_w - width img in pixels
1500
align 4
1501
proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword
1502
 
1503
  mov eax,dword[data_rgb] ;eax =
1504
  mov ecx,dword[size]	  ;ecx = size
1505
  lea ecx,[ecx+ecx*2]
1506
  cld
1507
  @@: ;затемнение цвета пикселей
1508
    shr byte[eax],1
1509
    inc eax
1510
    loop @b
1511
 
1512
  mov eax,dword[data_rgb] ;eax =
2920 IgorA 1513
  mov esi,dword[size_w]
1514
  lea esi,[esi+esi*2] ;esi = width*3(rgb)
1535 IgorA 1515
  mov ebx,esi
1516
  add ebx,eax
1517
  mov ecx,dword[size]  ;ecx = size
1518
  shr ecx,1
1519
  xor edi,edi
1520
  @@: ;сложение цветов пикселей
1521
    mov dx,word[ebx] ;копируем цвет нижнего пикселя
1522
    add word[eax],dx
1523
    mov dl,byte[ebx+2] ;копируем цвет нижнего пикселя
1524
    add byte[eax+2],dl
1525
 
1526
    add eax,3
1527
    add ebx,3
1528
    inc edi
1529
    cmp edi,dword[size_w]
1530
    jl .old_line
1531
      add eax,esi
1532
      add ebx,esi
1533
      xor edi,edi
1534
    .old_line:
1535
    loop @b
1536
 
1537
  mov eax,dword[data_rgb] ;eax =
1538
  add eax,esi ;esi = width*3(rgb)
2920 IgorA 1539
  mov ebx,eax
1540
  add ebx,esi
1535 IgorA 1541
  mov ecx,dword[size] ;ecx = size
1542
  shr ecx,1
1543
  sub ecx,dword[size_w] ;лишняя строка пикселей
1544
  xor edi,edi
1545
  @@: ;поджатие пикселей
1546
    mov edx,dword[ebx] ;копируем цвет нижнего пикселя
1547
    mov word[eax],dx
1548
    shr edx,16
1549
    mov byte[eax+2],dl
1550
 
1551
    add eax,3
1552
    add ebx,3
1553
    inc edi
1554
    cmp edi,dword[size_w]
1555
    jl .old_line_2
1556
      add ebx,esi
1557
      xor edi,edi
1558
    .old_line_2:
1559
    loop @b
1560
  ret
1561
endp
1562
 
2920 IgorA 1563
;input:
2927 IgorA 1564
;data_rgba - pointer to rgba data
1565
;size - count img pixels (size img data / 4(rgba) )
2920 IgorA 1566
;size_w_b - width img in bytes
1567
align 4
2927 IgorA 1568
proc img_rgba32_hdiv2, data_rgba:dword, size:dword, size_w_b:dword
2920 IgorA 1569
 
2927 IgorA 1570
	mov eax,dword[data_rgba] ;eax =
2920 IgorA 1571
	mov ebx,dword[size_w_b]
1572
	add ebx,eax
1573
	mov ecx,dword[size]  ;ecx = size
1574
	shr ecx,1
1575
	xor edi,edi
1576
	@@: ;смешивание цветов пикселей
1577
		call combine_colors_1
1578
		mov dword[eax],edx
1579
 
1580
		add eax,4
1581
		add ebx,4
1582
		add edi,4
1583
		cmp edi,dword[size_w_b]
1584
		jl .old_line
1585
			add eax,dword[size_w_b]
1586
			add ebx,dword[size_w_b]
1587
			xor edi,edi
1588
		.old_line:
1589
		loop @b
1590
 
2927 IgorA 1591
	mov eax,dword[data_rgba] ;eax =
2920 IgorA 1592
	mov ebx,dword[size_w_b]
1593
	add eax,ebx
1594
	add ebx,eax
1595
	mov ecx,dword[size] ;ecx = size
1596
	shl ecx,1
1597
	sub ecx,dword[size_w_b] ;лишняя строка пикселей
1598
	shr ecx,2
1599
	xor edi,edi
1600
	@@: ;поджатие пикселей
1601
		mov edx,dword[ebx] ;копируем цвет нижнего пикселя
1602
		mov dword[eax],edx
1603
 
1604
		add eax,4
1605
		add ebx,4
1606
		add edi,4
1607
		cmp edi,dword[size_w_b]
1608
		jl .old_line_2
1609
			add ebx,dword[size_w_b]
1610
			xor edi,edi
1611
		.old_line_2:
1612
		loop @b
1613
	ret
1614
endp
1615
 
1616
;input:
1617
; eax - указатель на 32-битный цвет
1618
; ebx - указатель на 32-битный цвет
1619
;output:
1620
; edx - 32-битный цвет смешанный с учетом прозрачности
1621
;destroy:
1622
; esi
1623
align 4
1624
proc combine_colors_1 uses ecx edi
1625
locals
1626
	c_blye dd ?
1627
	c_green dd ?
1628
	c_red dd ?
1629
endl
1630
	movzx edi,byte[eax+3]
1631
	cmp edi,255
1632
	je .c0z
1633
	movzx esi,byte[ebx+3]
1634
	cmp esi,255
1635
	je .c1z
2927 IgorA 1636
	cmp edi,esi
1637
	je .c0_c1
2920 IgorA 1638
 
1639
	;переворачиваем значения прозрачностей
1640
	neg edi
1641
	inc edi
1642
	add edi,255
1643
	neg esi
1644
	inc esi
1645
	add esi,255
1646
 
1647
	movzx ecx,byte[eax]
1648
	imul ecx,edi
1649
	mov [c_blye],ecx
1650
	movzx ecx,byte[ebx]
1651
	imul ecx,esi
1652
	add [c_blye],ecx
1653
 
1654
	movzx ecx,byte[eax+1]
1655
	imul ecx,edi
1656
	mov [c_green],ecx
1657
	movzx ecx,byte[ebx+1]
1658
	imul ecx,esi
1659
	add [c_green],ecx
1660
 
1661
	movzx ecx,byte[eax+2]
1662
	imul ecx,edi
1663
	mov [c_red],ecx
1664
	movzx ecx,byte[ebx+2]
1665
	imul ecx,esi
1666
	add [c_red],ecx
1667
 
1668
push eax ebx
1669
	xor ebx,ebx
1670
	mov eax,[c_red]
1671
	xor edx,edx
1672
	mov ecx,edi
1673
	add ecx,esi
1674
	div ecx
1675
	mov bl,al
1676
	shl ebx,16
1677
	mov eax,[c_green]
1678
	xor edx,edx
1679
	div ecx
1680
	mov bh,al
1681
	mov eax,[c_blye]
1682
	xor edx,edx
1683
	div ecx
1684
	mov bl,al
1685
 
1686
	shr ecx,1
1687
	;переворачиваем значения прозрачности
1688
	neg ecx
1689
	inc ecx
1690
	add ecx,255
1691
 
1692
	shl ecx,24
1693
	add ebx,ecx
1694
	mov edx,ebx
1695
pop ebx eax
1696
 
1697
	jmp .end_f
2927 IgorA 1698
	.c0_c1: ;если прозрачности обоих цветов совпадают
1699
		mov edx,dword[eax]
1700
		shr edx,1
1701
		and edx,011111110111111101111111b
1702
		mov esi,dword[ebx]
1703
		shr esi,1
1704
		and esi,011111110111111101111111b
1705
		add edx,esi
1706
		ror edi,8 ;перемещаем значение прозрачности в старший байт edi
1707
		or edx,edi
1708
		jmp .end_f
2920 IgorA 1709
	.c0z: ;если цвет в eax прозрачный
1710
		mov edx,dword[ebx]
1711
		movzx edi,byte[ebx+3]
1712
		jmp @f
1713
	.c1z: ;если цвет в ebx прозрачный
1714
		mov edx,dword[eax]
1715
	@@:
1716
		add edi,255 ;делаем цвет на половину прозрачным
1717
		shr edi,1
1718
		cmp edi,255
1719
		jl @f
1720
			mov edi,255 ;максимальная прозрачность не более 255
1721
		@@:
1722
		shl edi,24
1723
		and edx,0xffffff ;снимаем старую прозрачность
1724
		add edx,edi
1725
	.end_f:
1726
	ret
1727
endp
1728
 
6175 IgorA 1729
;description:
1730
; сжатие изображения по ширине (размеры буфера не меняются)
1731
;input:
1732
; data_rgb - pointer to rgb data
1733
; size_w - width img in pixels
1734
; size_h - height img in pixels
1735
; size_w_new - new width img in pixels
1736
align 16
1737
proc img_rgb24_wresize, data_rgb:dword, size_w:dword, size_h:dword, size_w_new:dword
1738
locals
1739
	pr dd 0
1740
	pg dd 0
1741
	pb dd 0
1742
	img_n dd ? ;указатель на данные нового изображения
1743
	lines dd ?
1744
endl
1745
pushad
1746
;eax - delta for inp. img
1747
;ebx - delta for outp. img
1748
;esi - pointer to data_rgb
1749
	mov esi,[data_rgb]
1750
	mov [img_n],esi
1751
	mov eax,[size_h]
1752
	mov [lines],eax
1753
align 4
1754
	.cycyle_0:
1755
	mov eax,[size_w_new]
1756
	mov ecx,[size_w]
1757
	mov ebx,ecx
1758
align 4
1759
	.cycyle_1:
1760
		cmp eax,ebx
1761
		jg .else_0
1762
			;копируемый пиксель максимально влияет на результат
1763
			;накапливаем rgb для интерполяции пикселей
1764
			mov edx,[size_w_new]
1765
			movzx edi,byte[esi]
1766
			imul edi,edx
1767
			add [pb],edi
1768
			movzx edi,byte[esi+1]
1769
			imul edi,edx
1770
			add [pg],edi
1771
			movzx edi,byte[esi+2]
1772
			imul edi,edx
1773
			add [pr],edi
1774
			cmp eax,ebx
1775
			je .d2_add
1776
			jmp .if_0_end
1777
		.else_0:
1778
			;копируемый пиксель попадет на границу пикселей
1779
			mov edx,ebx
1780
			sub edx,eax
1781
			add edx,[size_w_new]
1782
			movzx edi,byte[esi]
1783
			imul edi,edx
1784
			add [pb],edi
1785
			movzx edi,byte[esi+1]
1786
			imul edi,edx
1787
			add [pg],edi
1788
			movzx edi,byte[esi+2]
1789
			imul edi,edx
1790
			add [pr],edi
1791
			;сохраняем готовое rgb
1792
			.d2_add:
1793
			push eax
1794
				mov edi,[img_n]
1795
				mov eax,[pb]
1796
				xor edx,edx
1797
				div dword[size_w] ;eax /= [size_w]
1798
				stosb
1799
				mov eax,[pg]
1800
				xor edx,edx
1801
				div dword[size_w] ;eax /= [size_w]
1802
				stosb
1803
				mov eax,[pr]
1804
				xor edx,edx
1805
				div dword[size_w] ;eax /= [size_w]
1806
				stosb
1807
			pop eax
1808
			add dword[img_n],3 ;next pixel
1809
			;обновляем rgb для нового пикселя
1810
			mov edx,eax
1811
			sub edx,ebx
1812
			movzx edi,byte[esi]
1813
			imul edi,edx
1814
			mov [pb],edi
1815
			movzx edi,byte[esi+1]
1816
			imul edi,edx
1817
			mov [pg],edi
1818
			movzx edi,byte[esi+2]
1819
			imul edi,edx
1820
			mov [pr],edi
1821
			add ebx,[size_w]
1822
		.if_0_end:
1823
		add eax,[size_w_new]
1824
		add esi,3 ;next pixel
1825
		dec ecx
1826
		jnz .cycyle_1
1827
	dec dword[lines]
1828
	jnz .cycyle_0
1829
popad
1830
	ret
1831
endp
1832
 
1535 IgorA 1833
;преобразование буфера из 24-битного в 8-битный
1834
; spectr - определяет какой спектр брать при преобразовании 0-синий, 1-зеленый, 2-красный
1835
align 4
1836
proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
1837
	pushad
1838
	mov edi,dword[buf_struc]
1839
	cmp buf2d_bits,24
1840
	jne .error
1841
		mov eax,buf2d_w
1842
		mov ecx,buf2d_h
1843
		imul ecx,eax
1844
		mov esi,ecx
1845
		;ebx - память из которой копируется
1846
		;edx - память куда копируется
1847
		mov edx,buf2d_data
1848
		mov ebx,edx
1849
		cmp [spectr],3
1850
		jge @f
1851
			add ebx,[spectr]
1852
		@@:
1853
			mov al,byte[ebx]
1854
			mov byte[edx],al
1855
			add ebx,3
1856
			inc edx
1857
			loop @b
1858
		mov buf2d_bits,8
1859
		invoke mem.realloc,buf2d_data,esi ;уменьшаем память занимаемую буфером
1860
		jmp .end_conv
1861
	.error:
1862
		stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
1863
	.end_conv:
1864
	popad
1865
	ret
1866
endp
1867
 
1868
;преобразование буфера из 24-битного в 32-битный
1869
align 4
1870
proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
1871
	pushad
1872
	mov edi,dword[buf_struc]
1873
	cmp buf2d_bits,24
1874
	jne .error1
1875
		mov ecx,buf2d_w
1876
		mov ebx,buf2d_h
1877
		imul ebx,ecx
1878
		mov ecx,ebx ;ecx = size  8 b
1879
		shl ebx,2   ;ebx = size 32 b
1880
		invoke mem.realloc,buf2d_data,ebx ;увеличиваем память занимаемую буфером
1881
		mov buf2d_data,eax ;на случай если изменился указатель на данные
1882
		mov buf2d_bits,32
1883
		mov edx,ebx ;edx = size 32 b
1884
		sub ebx,ecx ;ebx = size 24 b
1885
		mov eax,ecx
1886
		;eax - размер  8 битных данных
1887
		;ebx - размер 24 битных данных
1888
		;edx - размер 32 битных данных
1889
		add ebx,buf2d_data
1890
		add edx,buf2d_data
1891
		mov edi,dword[buf_str8]
1892
		cmp buf2d_bits,8
1893
		jne .error2
1894
		add eax,buf2d_data
1895
		mov edi,edx
1896
		;eax - указатель на конец  8 битных данных
1897
		;ebx - указатель на конец 24 битных данных
1898
		;edi - указатель на конец 32 битных данных
1899
		@@:
1900
			sub edi,4 ;отнимаем в начале цикла,
1901
			sub ebx,3 ; потому, что указатели стоят
1902
			dec eax   ; за пределами буферов
1903
			mov edx,dword[ebx]
1904
			mov dword[edi],edx
1905
			mov dl,byte[eax]
1906
			mov byte[edi+3],dl
1907
			loop @b
1908
 
1909
		jmp .end_conv
1910
	.error1:
1911
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n24b
1912
		jmp .end_conv
1913
	.error2:
1914
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n8b
1915
	.end_conv:
1916
	popad
1917
	ret
1918
endp
1919
 
1920
;функция копирует изображение из буфера buf_source (24b|32b) в buf_destination (24b)
1921
; указываются координаты вставки буфера buf_source относительно buf_destination
1922
; прозрачность при копировании не учитывается
1923
align 4
1924
proc buf_bit_blt, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
1925
	locals
1926
		right_bytes dd ?
1927
	endl
1928
	pushad
1929
 
1930
	mov edi,[buf_source]
1931
	cmp buf2d_bits,24
1932
	je .sou24
1933
	cmp buf2d_bits,32
1934
	je .sou32
1935
		jmp .copy_end ;формат буфера не поодерживается
1936
 
1648 IgorA 1937
	.sou24: ;в источнике 24 битная картинка
1535 IgorA 1938
	mov eax,buf2d_w
1939
	mov edx,buf2d_h ;высота копируемой картинки
1940
	mov esi,buf2d_data ;данные копируемой картинки
1941
 
1942
	mov edi,[buf_destination]
1943
	cmp buf2d_bits,24
1944
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 1945
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
1946
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 1947
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 1948
		mov ebx,buf2d_h ;ebx - высота основного буфера
1949
		mov ecx,[coord_y]
2422 IgorA 1950
		cmp ecx,0
1951
		jge @f
1952
			;если координата coord_y<0 (1-я настройка)
1953
			add edx,ecx ;уменьшаем высоту копируемой картинки
1954
			cmp edx,0
1955
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
1956
			neg ecx
1957
			;inc ecx
1958
			imul ecx,eax
1959
			lea ecx,[ecx+ecx*2] ;по 3 байта на пиксель
1960
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
1961
			xor ecx,ecx ;обнуляем координату coord_y
1962
		@@:
1535 IgorA 1963
		cmp ecx,ebx
1964
		jge .copy_end ;если координата 'y' больше высоты буфера
1965
		add ecx,edx ;ecx - нижняя координата копируемой картинки
1966
		cmp ecx,ebx
1967
		jle @f
1968
			sub ecx,ebx
1969
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
1970
		@@:
1971
		mov ebx,buf2d_w
2422 IgorA 1972
		mov ecx,[coord_y] ;ecx используем для временных целей
1973
		cmp ecx,0
1974
		jg .end_otr_c_y_24
1975
			;если координата coord_y<=0 (2-я настройка)
1976
			mov ecx,[coord_x]
1977
			jmp @f
1978
		.end_otr_c_y_24:
1979
		imul ecx,ebx
1535 IgorA 1980
		add ecx,[coord_x]
2422 IgorA 1981
		@@:
1535 IgorA 1982
		lea ecx,[ecx+ecx*2]
1983
		add ecx,buf2d_data
1984
		sub ebx,eax
1985
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
1986
 
1987
	mov [right_bytes],0
1988
	mov ecx,[coord_x]
1989
	cmp ecx,ebx
1990
	jl @f
1991
		sub ecx,ebx
1992
		sub eax,ecx ;укорачиваем копируемую строку
1993
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
1994
		lea ecx,[ecx+ecx*2] ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
1995
		mov [right_bytes],ecx
1996
	@@:
1997
 
1998
	lea eax,[eax+eax*2] ;колличество байт в 1-й строке копируемой картинки
1999
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2000
 
2001
	cld
2002
	cmp [right_bytes],0
2003
	jg .copy_1
2004
	.copy_0: ;простое копирование
2005
		mov ecx,eax
2006
		rep movsb
2007
		add edi,ebx
2008
		dec edx
2009
		cmp edx,0
2010
		jg .copy_0
2011
	jmp .copy_end
2012
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2013
		mov ecx,eax
2014
		rep movsb
2015
		add edi,ebx
2016
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2017
		dec edx
2018
		cmp edx,0
2019
		jg .copy_1
2020
	jmp .copy_end
2021
 
2022
	.sou32: ;в источнике 32 битная картинка
2023
	mov eax,buf2d_w
2024
	mov edx,buf2d_h ;высота копируемой картинки
2025
	mov esi,buf2d_data ;данные копируемой картинки
2026
 
2027
	mov edi,[buf_destination]
2028
	cmp buf2d_bits,24
2029
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2030
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2031
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2032
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2033
		mov ebx,buf2d_h ;ebx - высота основного буфера
2034
		mov ecx,[coord_y]
2422 IgorA 2035
		cmp ecx,0
2036
		jge @f
2037
			;если координата coord_y<0 (1-я настройка)
2038
			add edx,ecx ;уменьшаем высоту копируемой картинки
2039
			cmp edx,0
2040
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2041
			neg ecx
2042
			;inc ecx
2043
			imul ecx,eax
2044
			shl ecx,2 ;по 4 байта на пиксель
2045
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2046
			xor ecx,ecx ;обнуляем координату coord_y
2047
		@@:
1535 IgorA 2048
		cmp ecx,ebx
2049
		jge .copy_end ;если координата 'y' больше высоты буфера
2050
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2051
		cmp ecx,ebx
2052
		jle @f
2053
			sub ecx,ebx
2054
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2055
		@@:
2056
		mov ebx,buf2d_w
2422 IgorA 2057
		;mov ecx,ebx ;ecx используем для временных целей
2058
		;imul ecx,[coord_y]
2059
		;add ecx,[coord_x]
2060
		mov ecx,[coord_y] ;ecx используем для временных целей
2061
		cmp ecx,0
2062
		jg .end_otr_c_y_32
2063
			;если координата coord_y<=0 (2-я настройка)
2064
			mov ecx,[coord_x]
2065
			jmp @f
2066
		.end_otr_c_y_32:
2067
		imul ecx,ebx
1535 IgorA 2068
		add ecx,[coord_x]
2422 IgorA 2069
		@@:
1535 IgorA 2070
		lea ecx,[ecx+ecx*2]
2071
		add ecx,buf2d_data
2072
		sub ebx,eax
2073
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2074
 
2075
	mov [right_bytes],0
2076
	mov ecx,[coord_x]
2077
	cmp ecx,ebx
2078
	jl @f
2079
		sub ecx,ebx
2080
		sub eax,ecx ;укорачиваем копируемую строку
2081
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2082
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2083
		mov [right_bytes],ecx
2084
	@@:
2085
 
2086
	;eax - колличество пикселей в 1-й строке копируемой картинки
2087
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2088
 
2089
	cld
2090
	cmp [right_bytes],0
2091
	jg .copy_3
2092
	.copy_2: ;простое копирование
2093
		mov ecx,eax
2094
		@@:
2095
			movsw
2096
			movsb
2097
			inc esi
2098
			loop @b
2099
		add edi,ebx
2100
		dec edx
2101
		cmp edx,0
2102
		jg .copy_2
2103
	jmp .copy_end
2104
	.copy_3: ;не простое копирование (картинка вылазит за правую сторону)
2105
		mov ecx,eax
2106
		@@:
2107
			movsw
2108
			movsb
2109
			inc esi
2110
			loop @b
2111
		add edi,ebx
2112
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2113
		dec edx
2114
		cmp edx,0
2115
		jg .copy_3
2116
 
2117
	.copy_end:
2118
	popad
2119
	ret
2120
endp
2121
 
2122
;input:
2123
; esi = pointer to color1 + transparent
2124
; edi = pointer to background color2
2125
;output:
2126
; [edi] = combine color
2127
align 4
2920 IgorA 2128
combine_colors_0:
1535 IgorA 2129
	push ax bx cx dx
2130
	mov bx,0x00ff ;---get transparent---
2748 IgorA 2131
	movzx cx,byte[esi+3] ;pro
1535 IgorA 2132
	sub bx,cx ;256-pro
1653 IgorA 2133
	;---blye---
2748 IgorA 2134
	movzx ax,byte[esi]
1535 IgorA 2135
	imul ax,bx
2748 IgorA 2136
	movzx dx,byte[edi]
1535 IgorA 2137
	imul dx,cx
2138
	add ax,dx
1653 IgorA 2139
	mov byte[edi],ah
1535 IgorA 2140
	;---green---
2748 IgorA 2141
	movzx ax,byte[esi+1]
1535 IgorA 2142
	imul ax,bx
2748 IgorA 2143
	movzx dx,byte[edi+1]
1535 IgorA 2144
	imul dx,cx
2145
	add ax,dx
2146
	mov byte[edi+1],ah
1653 IgorA 2147
	;---red---
2748 IgorA 2148
	movzx ax,byte[esi+2]
1535 IgorA 2149
	imul ax,bx
2748 IgorA 2150
	movzx dx,byte[edi+2]
1535 IgorA 2151
	imul dx,cx
2152
	add ax,dx
1653 IgorA 2153
	mov byte[edi+2],ah
1535 IgorA 2154
 
2155
	pop dx cx bx ax
2156
	ret
2157
 
2158
;функция копирует изображение из буфера buf_source (32b) в buf_destination (24b)
2159
; указываются координаты вставки буфера buf_source относительно buf_destination
2160
; при копировании учитывается прозрачность
2161
align 4
2162
proc buf_bit_blt_transp, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
2163
	locals
2927 IgorA 2164
		lost_bytes dd ?
1535 IgorA 2165
	endl
2166
	pushad
2167
 
2168
	mov edi,[buf_source]
2169
	cmp buf2d_bits,32
2170
	jne .copy_end ;формат буфера не поодерживается
2171
	mov eax,buf2d_w
2172
	mov edx,buf2d_h ;высота копируемой картинки
2173
	mov esi,buf2d_data ;данные копируемой картинки
2174
 
2175
	mov edi,[buf_destination]
2176
	cmp buf2d_bits,24
2177
	jne .copy_end ;формат буфера не поодерживается
2178
		mov ebx,buf2d_h ;ebx - высота основного буфера
2179
		mov ecx,[coord_y]
2383 IgorA 2180
		cmp ecx,0
2181
		jge @f
2182
			;если координата coord_y<0 (1-я настройка)
2183
			add edx,ecx ;уменьшаем высоту копируемой картинки
2184
			cmp edx,0
2185
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2186
			neg ecx
2187
			;inc ecx
2188
			imul ecx,eax
2422 IgorA 2189
			shl ecx,2 ;по 4 байта на пиксель
2383 IgorA 2190
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2191
			xor ecx,ecx ;обнуляем координату coord_y
2192
		@@:
1535 IgorA 2193
		cmp ecx,ebx
2194
		jge .copy_end ;если координата 'y' больше высоты буфера
2195
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2196
		cmp ecx,ebx
2197
		jle @f
2198
			sub ecx,ebx
2199
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2200
		@@:
2201
		mov ebx,buf2d_w
2202
		mov ecx,ebx ;ecx используем для временных целей
2383 IgorA 2203
		cmp [coord_y],0
2204
		jg .end_otr_c_y
2205
			;если координата coord_y<=0 (2-я настройка)
2206
			mov ecx,[coord_x]
2207
			jmp @f
2208
		.end_otr_c_y:
1535 IgorA 2209
		imul ecx,[coord_y]
2210
		add ecx,[coord_x]
2383 IgorA 2211
		@@:
1535 IgorA 2212
		lea ecx,[ecx+ecx*2]
2213
		add ecx,buf2d_data
2214
		sub ebx,eax
2215
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2216
 
2927 IgorA 2217
	mov dword[lost_bytes],0
1535 IgorA 2218
	mov ecx,[coord_x]
2927 IgorA 2219
	cmp ecx,0
2220
	jge @f
2221
		neg ecx
2222
		;inc ecx
2223
		cmp eax,ecx ;eax - ширина копируемой картинки
2224
		jle .copy_end ;если копируемое изображение находится полностью за левой границей буфера (coord_x<0 и |coord_x|>buf_source.w)
2225
		shl ecx,2
2226
		mov [lost_bytes],ecx
2227
		add esi,ecx
2228
		shr ecx,2
2229
		sub eax,ecx ;укорачиваем копируемую строку
2230
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2231
		lea ecx,[ecx+ecx*2]
2232
		add edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2233
		xor ecx,ecx
2234
	@@:
1535 IgorA 2235
	cmp ecx,ebx
2927 IgorA 2236
	jle @f
1535 IgorA 2237
		sub ecx,ebx
2238
		sub eax,ecx ;укорачиваем копируемую строку
2239
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2927 IgorA 2240
		shl ecx,2 ;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
2241
		add [lost_bytes],ecx
1535 IgorA 2242
	@@:
2243
 
2927 IgorA 2244
;	mov [right_bytes],0
2245
;	mov ecx,[coord_x]
2246
;	cmp ecx,ebx
2247
;	jl @f
2248
;		sub ecx,ebx
2249
;		sub eax,ecx ;укорачиваем копируемую строку
2250
;		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2251
;		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2252
;		mov [right_bytes],ecx
2253
;	@@:
2254
 
1535 IgorA 2255
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2658 IgorA 2256
 
1535 IgorA 2257
	cld
2927 IgorA 2258
	cmp [lost_bytes],0
1535 IgorA 2259
	jg .copy_1
2260
	.copy_0: ;простое копирование
2261
		mov ecx,eax
2262
		@@:
2920 IgorA 2263
			call combine_colors_0
1535 IgorA 2264
			add edi,3
2265
			add esi,4
2266
			loop @b
2267
		add edi,ebx
2268
		dec edx
2269
		cmp edx,0
2270
		jg .copy_0
2271
	jmp .copy_end
2272
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2273
		mov ecx,eax
2274
		@@:
2920 IgorA 2275
			call combine_colors_0
1535 IgorA 2276
			add edi,3
2277
			add esi,4
2278
			loop @b
2279
		add edi,ebx
2927 IgorA 2280
		add esi,[lost_bytes] ;добавляем байты, которые вылазят за правую границу
1535 IgorA 2281
		dec edx
2282
		cmp edx,0
2283
		jg .copy_1
2284
 
2285
	.copy_end:
2286
	popad
2287
	ret
2288
endp
2289
 
2290
;input:
2291
; ebx - color1
2292
; esi = pointer to transparent
2293
; edi = pointer to background color2
2294
;output:
2295
; [edi] = combine color
2296
align 4
2297
combine_colors_2:
2298
	push ax ebx cx dx si
2299
	mov cl,byte[esi] ;pro
2300
	xor ch,ch
2301
	mov si,0x00ff ;---get transparent---
2302
	sub si,cx ;256-pro
2303
 
1653 IgorA 2304
		;---blye---
2748 IgorA 2305
		movzx ax,bl
1535 IgorA 2306
		shr ebx,8
2307
		imul ax,si
2748 IgorA 2308
		movzx dx,byte[edi]
1535 IgorA 2309
		imul dx,cx
2310
		add ax,dx
1653 IgorA 2311
		mov byte[edi],ah
1535 IgorA 2312
		;---green---
2748 IgorA 2313
		movzx ax,bl
1535 IgorA 2314
		shr ebx,8
2315
		imul ax,si
2748 IgorA 2316
		movzx dx,byte[edi+1]
1535 IgorA 2317
		imul dx,cx
2318
		add ax,dx
2319
		mov byte[edi+1],ah
2320
		;---red---
2748 IgorA 2321
		movzx ax,bl
1535 IgorA 2322
		imul ax,si
2748 IgorA 2323
		movzx dx,byte[edi+2]
1535 IgorA 2324
		imul dx,cx
2325
		add ax,dx
1653 IgorA 2326
		mov byte[edi+2],ah
1535 IgorA 2327
 
2328
	pop si dx cx ebx ax
2329
	ret
2330
 
2331
;функция копирует изображение из буфера buf_source (8b) в buf_destination (24b)
2332
; указываются координаты вставки буфера buf_source относительно buf_destination
2333
align 4
2334
proc buf_bit_blt_alpha, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword, color:dword
2335
	locals
2383 IgorA 2336
		lost_bytes dd ? ;число потерянных байтов в строке копируемого изображеня (тех что не влазят в буфер)
1535 IgorA 2337
		dest_w_bytes dd ? ;колличество байт в буфере приемнике по ширине - ширина вставляемой картинки
2338
	endl
2339
	pushad
2340
 
2341
	mov edi,[buf_source]
2342
	cmp buf2d_bits,8
2343
	jne .error1 ;формат буфера не поодерживается
2383 IgorA 2344
	mov eax,buf2d_w ;ширина копируемой картинки
1535 IgorA 2345
	mov edx,buf2d_h ;высота копируемой картинки
2346
	mov esi,buf2d_data ;данные копируемой картинки
2347
 
2348
	mov edi,[buf_destination]
2349
	cmp buf2d_bits,24
2350
	jne .error2 ;формат буфера не поодерживается
1642 IgorA 2351
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2352
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2353
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2354
		mov ebx,buf2d_h ;ebx - высота основного буфера
2355
		mov ecx,[coord_y]
2367 IgorA 2356
		cmp ecx,0
2357
		jge @f
2358
			;если координата coord_y<0 (1-я настройка)
2359
			add edx,ecx ;уменьшаем высоту копируемой картинки
2383 IgorA 2360
			cmp edx,0
2361
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2367 IgorA 2362
			neg ecx
2363
			;inc ecx
2364
			imul ecx,eax
2365
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2366
			xor ecx,ecx ;обнуляем координату coord_y
2367
		@@:
1535 IgorA 2368
		cmp ecx,ebx
2369
		jge .copy_end ;если координата 'y' больше высоты буфера
2370
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2371
		cmp ecx,ebx
2372
		jle @f
2373
			sub ecx,ebx
2374
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2375
		@@:
2376
		mov ebx,buf2d_w
2367 IgorA 2377
		mov ecx,[coord_y] ;ecx используем для временных целей
2378
		cmp ecx,0
2383 IgorA 2379
		jg .end_otr_c_y
2380
			;если координата coord_y<=0 (2-я настройка)
2367 IgorA 2381
			mov ecx,[coord_x]
2382
			jmp @f
2383
		.end_otr_c_y:
2384
		imul ecx,ebx
1535 IgorA 2385
		add ecx,[coord_x]
2367 IgorA 2386
		@@:
1535 IgorA 2387
		lea ecx,[ecx+ecx*2]
2383 IgorA 2388
		add ecx,buf2d_data ;buf2d_data данные основного буфера
2389
		sub ebx,eax ;ebx - ширина основного буфера минус ширина рисуемого буфера
1535 IgorA 2390
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2391
 
2383 IgorA 2392
	mov dword[lost_bytes],0
1535 IgorA 2393
	mov ecx,[coord_x]
2383 IgorA 2394
	cmp ecx,0
2395
	jge @f
2396
		neg ecx
2397
		;inc ecx
2398
		cmp eax,ecx ;eax - ширина копируемой картинки
2399
		jle .copy_end ;если копируемое изображение находится полностью за левой границей буфера (coord_x<0 и |coord_x|>buf_source.w)
2927 IgorA 2400
		mov [lost_bytes],ecx
2383 IgorA 2401
		sub eax,ecx ;укорачиваем копируемую строку
2402
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2403
		add esi,ecx
2404
		lea ecx,[ecx+ecx*2]
2405
		add edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2406
		xor ecx,ecx
2407
	@@:
1535 IgorA 2408
	cmp ecx,ebx
2383 IgorA 2409
	jle @f
1535 IgorA 2410
		sub ecx,ebx
2411
		sub eax,ecx ;укорачиваем копируемую строку
2412
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2413
		;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
2383 IgorA 2414
		add [lost_bytes],ecx
1535 IgorA 2415
	@@:
2416
 
2417
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2418
	mov [dest_w_bytes],ebx
2419
	mov ebx,[color]
2420
 
2421
	cld
2383 IgorA 2422
	cmp dword[lost_bytes],0
1535 IgorA 2423
	jg .copy_1
2424
	.copy_0: ;простое копирование
2425
		mov ecx,eax
2426
		@@:
2427
			call combine_colors_2
2428
			add edi,3
2429
			inc esi
2430
			loop @b
2431
		add edi,[dest_w_bytes]
2432
		dec edx
2433
		cmp edx,0
2434
		jg .copy_0
2435
	jmp .copy_end
2383 IgorA 2436
	.copy_1: ;не простое копирование (картинка вылазит за левую и/или правую сторону)
1535 IgorA 2437
		mov ecx,eax
2438
		@@:
2439
			call combine_colors_2
2440
			add edi,3
2441
			inc esi
2442
			loop @b
2443
		add edi,[dest_w_bytes]
2383 IgorA 2444
		add esi,[lost_bytes] ;добавляем байты, которые вылазят за правую границу
1535 IgorA 2445
		dec edx
2446
		cmp edx,0
2447
		jg .copy_1
2448
 
2449
	jmp .copy_end
2450
	.error1:
2451
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n8b
2452
		jmp .copy_end
2453
	.error2:
2454
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n24b
2455
	.copy_end:
2456
	popad
2457
	ret
2458
endp
2459
 
2460
align 4
2461
proc print_err, fun:dword, mes:dword ;выводим сообщение об шибке на доску отладки
2462
	pushad
2463
	mov eax,63
2464
	mov ebx,1
2465
 
2466
	mov esi,[fun]
2467
	@@:
2468
		mov cl,byte[esi]
2469
		int 0x40
2470
		inc esi
2471
		cmp byte[esi],0
2472
		jne @b
2473
	mov cl,':'
2474
	int 0x40
2475
	mov cl,' '
2476
	int 0x40
2477
	mov esi,[mes]
2478
	@@:
2479
		mov cl,byte[esi]
2480
		int 0x40
2481
		inc esi
2482
		cmp byte[esi],0
2483
		jne @b
2484
	popad
2485
	ret
2486
endp
2487
 
3138 heavyiron 2488
;фильтр
3105 IgorA 2489
align 4
2490
proc buf_filter_dither, buffer:dword, algor:dword
2491
	pushad
2492
	mov edi,[buffer]
2493
	cmp buf2d_bits,24
2494
	jne .error
2495
		mov edx,buf2d_w
2496
		mov esi,buf2d_h
2497
		mov edi,buf2d_data
2498
;edi - pointer to 24bit bitmap
2499
;edx - x size
2500
;esi - y size
3138 heavyiron 2501
		lea   edx,[edx+edx*2]
3105 IgorA 2502
		imul  esi,edx
2748 IgorA 2503
 
3105 IgorA 2504
		;определяем какой алгоритм использовать
2505
		cmp dword[algor],0
2506
		jne @f
2507
			call dither_0
2508
			jmp .dither_end
2509
		@@:
2510
		cmp dword[algor],1
2511
		jne @f
2512
			call dither_1
2513
			jmp .dither_end
2514
		@@:
3138 heavyiron 2515
		cmp dword[algor],2
2516
		jne @f
2517
			call dither_2
2518
			jmp .dither_end
2519
		@@:
2520
		cmp dword[algor],3
2521
		jne @f
2522
			call dither_3
2523
			jmp .dither_end
2524
		@@:
2525
		call dither_4
3105 IgorA 2526
		jmp .dither_end
2527
	.error:
2528
		stdcall print_err,sz_buf2d_filter_dither,txt_err_n24b
2529
	.dither_end:
2530
	popad
2531
	ret
2532
endp
2748 IgorA 2533
 
3105 IgorA 2534
align 16
3138 heavyiron 2535
dither_0: ; Sierra Filter Lite algorithm
3105 IgorA 2536
newp_0:   ; Dithering cycle
2537
	xor   ebx,ebx ; At first threshold
2538
	movzx ecx,byte[edi]
2539
	cmp   cl,255
2540
	je    newp_0.next
2541
	test  cl,cl
2542
	jz    newp_0.next
2543
	jns   @f
2544
	dec   ebx
2545
	sub   ecx,255
2546
@@:
2547
	mov   [edi],bl               ; putpixel
2548
 
2549
	sar   ecx,1                  ; error/2
2550
	;adc   ecx,0                  ; round to integer
2551
 
2552
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
2553
	add   eax,ecx                ; add error/2 to (x+1;y)
2554
	jge   @f                     ; check_overflow
2555
	xor   eax,eax
2556
	jmp   .ok
2557
@@:
2558
	cmp   eax,255
2559
	jle   .ok
2560
	or    al,255
2561
.ok:
2562
	mov   [edi+3],al             ; putpixel
2563
 
2564
	sar   ecx,1                  ; error/4
2565
	adc   ecx,0                  ; round to integer
2566
 
2567
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
2568
	add   eax,ecx                ; add error/4 to (x-1;y+1)
2569
	jge   @f                     ; check_overflow
2570
	xor   eax,eax
2571
	jmp   .ok1
2572
@@:
2573
	cmp   eax,255
2574
	jle   .ok1
2575
	or    al,255
2576
.ok1:
2577
	mov   [edi+edx-3],al         ; putpixel
2578
 
2579
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
2580
	add   eax,ecx                ; add error/4 to (x;y+1)
2581
	jge   @f                     ; check_overflow
2582
	xor   eax,eax
2583
	jmp   .ok2
2584
@@:
2585
	cmp   eax,255
2586
	jle   .ok2
2587
	or    al,255
2588
.ok2:
2589
	mov   [edi+edx],al           ; putpixel
2590
 
2591
.next:
2592
	inc   edi
2593
	dec   esi
2594
	jnz   newp_0
2595
	ret
2596
 
2597
align 16
3138 heavyiron 2598
dither_1: ; Floyd-Steinberg algorithm
3105 IgorA 2599
newp_1:   ; Dithering cycle
2600
	xor   ebx,ebx ; At first threshold
2601
	movzx ecx,byte[edi]
2602
	cmp   cl,255
2603
	je    newp_1.next
2604
	test  cl,cl
2605
	jz    newp_1.next
2606
	jns   @f
2607
	dec   ebx
2608
	sub   ecx,255
2609
@@:
2610
	mov   [edi],bl               ; putpixel
2611
 
2612
	sar   ecx,4                  ; error/16
2613
	adc   ecx,0                  ; round to integer
2614
	mov   ebx,ecx
2615
 
2616
	movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
2617
	add   eax,ecx                ; add error/16 to (x+1;y+1)
2618
	jge   @f                     ; check_overflow
2619
	xor   eax,eax
2620
	jmp   .ok
2621
@@:
2622
	cmp   eax,255
2623
	jle   .ok
2624
	or    al,255
2625
.ok:
2626
	mov   [edi+edx+3],al         ;putpixel
2627
 
2628
	imul  ecx,3
2629
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
2630
	add   eax,ecx                ; add 3*error/16 to (x-1;y+1)
2631
	jge   @f                     ; check_overflow
2632
	xor   eax,eax
2633
	jmp   .ok1
2634
@@:
2635
	cmp   eax,255
2636
	jle   .ok1
2637
	or    al,255
2638
.ok1:
2639
	mov   [edi+edx-3],al         ;putpixel
2640
 
2641
	mov   ecx,ebx
2642
	imul  ecx,5
2643
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
2644
	add   eax,ecx                ; add 5*error/16 to (x;y+1)
2645
	jge   @f                     ; check_overflow
2646
	xor   eax,eax
2647
	jmp   .ok2
2648
@@:
2649
	cmp   eax,255
2650
	jle   .ok2
2651
	or    al,255
2652
.ok2:
2653
	mov   [edi+edx],al           ;putpixel
2654
 
2655
	mov   ecx,ebx
2656
	imul  ecx,7
2657
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
2658
	add   eax,ecx                ; add 7*error/16 to (x+1;y)
2659
	jge   @f                     ; check_overflow
2660
	xor   eax,eax
2661
	jmp   .ok3
2662
@@:
2663
	cmp   eax,255
2664
	jle   .ok3
2665
	or    al,255
2666
.ok3:
2667
	mov   [edi+3],al             ;putpixel
2668
 
2669
.next:
2670
	inc  edi
2671
	dec  esi
2672
	jnz  newp_1
2673
	ret
2674
 
2675
align 16
3138 heavyiron 2676
dither_2: ; Burkes algorithm
3105 IgorA 2677
newp_2:   ; Dithering cycle
2678
	xor   ebx,ebx ; At first threshold
2679
	movsx ecx,byte[edi]
2680
	cmp   cl,255
2681
	je    newp_2.next
2682
	test  cl,cl
2683
	jz    newp_2.next
2684
	jns   @f
2685
	dec   ebx
2686
@@:
2687
	mov   [edi],bl               ; putpixel
2688
 
2689
	sar   ecx,2                  ; error/4
2690
	adc   ecx,0                  ; round to integer
2691
 
2692
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
2693
	add   eax,ecx                ; add error/4 to (x+1;y)
2694
	jge   @f                     ; check_overflow
2695
	xor   eax,eax
2696
	jmp   .ok
2697
@@:
2698
	cmp   eax,255
2699
	jle   .ok
2700
	or    al,255
2701
.ok:
2702
	mov   [edi+3],al             ; putpixel
2703
 
2704
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
2705
	add   eax,ecx                ; add error/4 to (x;y+1)
2706
	jge   @f                     ; check_overflow
2707
	xor   eax,eax
2708
	jmp   .ok1
2709
@@:
2710
	cmp   eax,255
2711
	jle   .ok1
2712
	or    al,255
2713
.ok1:
2714
	mov   [edi+edx],al           ; putpixel
2715
 
2716
	sar   ecx,1                  ; error/8
2717
	adc   ecx,0                  ; round to integer
2718
 
2719
	movzx eax,byte[edi+6]        ; pixel (x+2;y)
2720
	add   eax,ecx                ; add error/8 to (x+2;y)
2721
	jge   @f                     ; check_overflow
2722
	xor   eax,eax
2723
	jmp   .ok2
2724
@@:
2725
	cmp   eax,255
2726
	jle   .ok2
2727
	or    al,255
2728
.ok2:
2729
	mov   [edi+6],al             ; putpixel
2730
 
2731
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
2732
	add   eax,ecx                ; add error/8 to (x-1;y+1)
2733
	jge   @f                     ; check_overflow
2734
	xor   eax,eax
2735
	jmp   .ok3
2736
@@:
2737
	cmp   eax,255
2738
	jle   .ok3
2739
	or    al,255
2740
.ok3:
2741
	mov   [edi+edx-3],al         ; putpixel
2742
 
2743
	movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
2744
	add   eax,ecx                ; add error/8 to (x+1;y+1)
2745
	jge   @f                     ; check_overflow
2746
	xor   eax,eax
2747
	jmp   .ok4
2748
@@:
2749
	cmp   eax,255
2750
	jle   .ok4
2751
	or    al,255
2752
.ok4:
2753
	mov   [edi+edx+3],al         ; putpixel
2754
 
2755
	sar   ecx,1                  ; error/16
2756
	;adc   ecx,0                  ; round to integer
2757
 
2758
	movzx eax,byte[edi+edx-6]    ; pixel (x-2;y+1)
2759
	add   eax,ecx                ; add error/16 to (x-2;y+1)
2760
	jge   @f                     ; check_overflow
2761
	xor   eax,eax
2762
	jmp   .ok5
2763
@@:
2764
	cmp   eax,255
2765
	jle   .ok5
2766
	or    al,255
2767
.ok5:
2768
	mov   [edi+edx-6],al         ; putpixel
2769
 
2770
	movzx eax,byte[edi+edx+6]    ; pixel (x+2;y+1)
2771
	add   eax,ecx                ; add error/16 to (x+2;y+1)
2772
	jge   @f                     ; check_overflow
2773
	xor   eax,eax
2774
	jmp   .ok6
2775
@@:
2776
	cmp   eax,255
2777
	jle   .ok6
2778
	or    al,255
2779
.ok6:
2780
	mov   [edi+edx+6],al         ; putpixel
2781
 
2782
.next:
2783
	inc   edi
2784
	dec   esi
2785
	jnz   newp_2
2786
	ret
2787
 
2788
 
3138 heavyiron 2789
align 16
2790
dither_3:                        ; Heavyiron_mod algorithm
2791
 newp_3:                         ; Dithering cycle
2792
    xor   ebx,ebx                ; At first threshold
2793
    movzx ecx,byte[edi]
2794
    cmp   cl,255
2795
    je   .next
2796
    test  cl,cl
2797
    jz    .next
2798
    jns   @f
2799
    dec   ebx
2800
    sub   ecx,255
2801
  @@:
2802
    mov   [edi],bl               ; putpixel
3105 IgorA 2803
 
3138 heavyiron 2804
    sar   ecx,2                  ; error/4
2805
 
2806
    movzx eax,byte[edi+3]        ; pixel (x+1;y)
2807
    add   eax,ecx                ; add error/4 to (x+1;y)
2808
    jge   @f                     ; check_overflow
2809
    xor   eax,eax
2810
    jmp   .ok
2811
  @@:
2812
    cmp   eax,255
2813
    jle   .ok
2814
    or    al,255
2815
  .ok:
2816
    mov   [edi+3],al             ; putpixel
2817
 
2818
    movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
2819
    add   eax,ecx                ; add error/4 to (x-1;y+1)
2820
    jge   @f                     ; check_overflow
2821
    xor   eax,eax
2822
    jmp   .ok1
2823
  @@:
2824
    cmp   eax,255
2825
    jle   .ok1
2826
    or    al,255
2827
  .ok1:
2828
    mov   [edi+edx-3],al         ; putpixel
2829
 
2830
    movzx eax,byte[edi+edx]      ; pixel (x;y+1)
2831
    add   eax,ecx                ; add error/4 to (x;y+1)
2832
    jge   @f                     ; check_overflow
2833
    xor   eax,eax
2834
    jmp   .ok2
2835
  @@:
2836
    cmp   eax,255
2837
    jle   .ok2
2838
    or    al,255
2839
  .ok2:
2840
    mov   [edi+edx],al           ; putpixel
2841
 
2842
  .next:
2843
    inc   edi
2844
    dec   esi
2845
    jnz   newp_3
2846
    ret
2847
 
2848
align 16
2849
dither_4:                        ; Atkinson algorithm
2850
 newp_4:                         ; Dithering cycle
2851
 
2852
    xor   ebx,ebx                ; At first threshold
2853
    movsx ecx,byte[edi]
2854
    cmp   cl,255
2855
    je   .next
2856
    test  cl,cl
2857
    jz    .next
2858
    jns   @f
2859
    dec   ebx
2860
  @@:
2861
    mov   [edi],bl               ; putpixel
2862
 
2863
    sar   ecx,3                  ; error/8
2864
 
2865
    movzx eax,byte[edi+3]        ; pixel (x+1;y)
2866
    add   eax,ecx                ; add error/8 to (x+1;y)
2867
    jge   @f                     ; check_overflow
2868
    xor   eax,eax
2869
    jmp   .ok
2870
  @@:
2871
    cmp   eax,255
2872
    jle   .ok
2873
    or    al,255
2874
  .ok:
2875
    mov   [edi+3],al             ; putpixel
2876
 
2877
    movzx eax,byte[edi+edx]      ; pixel (x;y+1)
2878
    add   eax,ecx                ; add error/8 to (x;y+1)
2879
    jge   @f                     ; check_overflow
2880
    xor   eax,eax
2881
    jmp   .ok1
2882
  @@:
2883
    cmp   eax,255
2884
    jle   .ok1
2885
    or    al,255
2886
  .ok1:
2887
    mov   [edi+edx],al           ; putpixel
2888
 
2889
    movzx eax,byte[edi+6]        ; pixel (x+2;y)
2890
    add   eax,ecx                ; add error/8 to (x+2;y)
2891
    jge   @f                     ; check_overflow
2892
    xor   eax,eax
2893
    jmp   .ok2
2894
  @@:
2895
    cmp   eax,255
2896
    jle   .ok2
2897
    or    al,255
2898
  .ok2:
2899
    mov   [edi+6],al             ; putpixel
2900
 
2901
    movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
2902
    add   eax,ecx                ; add error/8 to (x-1;y+1)
2903
    jge   @f                     ; check_overflow
2904
    xor   eax,eax
2905
    jmp   .ok3
2906
  @@:
2907
    cmp   eax,255
2908
    jle   .ok3
2909
    or    al,255
2910
  .ok3:
2911
    mov   [edi+edx-3],al         ; putpixel
2912
 
2913
    movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
2914
    add   eax,ecx                ; add error/8 to (x+1;y+1)
2915
    jge   @f                     ; check_overflow
2916
    xor   eax,eax
2917
    jmp   .ok4
2918
  @@:
2919
    cmp   eax,255
2920
    jle   .ok4
2921
    or    al,255
2922
  .ok4:
2923
    mov   [edi+edx+3],al         ; putpixel
2924
 
2925
 
2926
    movzx eax,byte[edi+edx+edx]    ; pixel (x;y+2)
2927
    add   eax,ecx                ; add error/8 to (x;y+2)
2928
    jge   @f                     ; check_overflow
2929
    xor   eax,eax
2930
    jmp   .ok5
2931
  @@:
2932
    cmp   eax,255
2933
    jle   .ok5
2934
    or    al,255
2935
  .ok5:
2936
    mov   [edi+edx+edx],al         ; putpixel
2937
 
2938
  .next:
2939
    inc   edi
2940
    dec   esi
2941
    jnz   newp_4
2942
    ret
2943
 
2944
 
2748 IgorA 2945
 
6175 IgorA 2946
include 'fun_voxel.inc' ;функции для работы с воксельной графикой
2748 IgorA 2947
 
1535 IgorA 2948
txt_err_n8b db 'need buffer 8 bit',13,10,0
2949
txt_err_n24b db 'need buffer 24 bit',13,10,0
2815 IgorA 2950
txt_err_n32b db 'need buffer 32 bit',13,10,0
2358 IgorA 2951
txt_err_n8_24b db 'need buffer 8 or 24 bit',13,10,0
1535 IgorA 2952
 
2953
align 16
2954
EXPORTS:
2955
	dd sz_lib_init, lib_init
2956
	dd sz_buf2d_create, buf_create
2957
	dd sz_buf2d_create_f_img, buf_create_f_img
2958
	dd sz_buf2d_clear, buf_clear
2959
	dd sz_buf2d_draw, buf_draw_buf
2960
	dd sz_buf2d_delete, buf_delete
2136 IgorA 2961
	dd sz_buf2d_resize, buf_resize
2975 IgorA 2962
	dd sz_buf2d_rotate, buf_rotate
1535 IgorA 2963
	dd sz_buf2d_line, buf_line_brs
2230 IgorA 2964
	dd sz_buf2d_line_sm, buf_line_brs_sm
1634 IgorA 2965
	dd sz_buf2d_rect_by_size, buf_rect_by_size
1642 IgorA 2966
	dd sz_buf2d_filled_rect_by_size, buf_filled_rect_by_size
1535 IgorA 2967
	dd sz_buf2d_circle, buf_circle
2968
	dd sz_buf2d_img_hdiv2, buf_img_hdiv2
2969
	dd sz_buf2d_img_wdiv2, buf_img_wdiv2
2970
	dd sz_buf2d_conv_24_to_8, buf_conv_24_to_8
2971
	dd sz_buf2d_conv_24_to_32, buf_conv_24_to_32
2972
	dd sz_buf2d_bit_blt, buf_bit_blt
2973
	dd sz_buf2d_bit_blt_transp, buf_bit_blt_transp
2974
	dd sz_buf2d_bit_blt_alpha, buf_bit_blt_alpha
1727 IgorA 2975
	dd sz_buf2d_curve_bezier, buf_curve_bezier
1535 IgorA 2976
	dd sz_buf2d_convert_text_matrix, buf_convert_text_matrix
2977
	dd sz_buf2d_draw_text, buf_draw_text
2978
	dd sz_buf2d_crop_color, buf_crop_color
2979
	dd sz_buf2d_offset_h, buf_offset_h
1684 IgorA 2980
	dd sz_buf2d_flood_fill, buf_flood_fill
1910 IgorA 2981
	dd sz_buf2d_set_pixel, buf_set_pixel
2658 IgorA 2982
	dd sz_buf2d_get_pixel, buf_get_pixel
5389 IgorA 2983
	dd sz_buf2d_flip_h, buf_flip_h
3040 IgorA 2984
	dd sz_buf2d_flip_v, buf_flip_v
3105 IgorA 2985
	dd sz_buf2d_filter_dither, buf_filter_dither
2748 IgorA 2986
	dd sz_buf2d_vox_brush_create, vox_brush_create
2987
	dd sz_buf2d_vox_brush_delete, vox_brush_delete
2758 IgorA 2988
	dd sz_buf2d_vox_obj_get_img_w_3g, buf_vox_obj_get_img_w_3g
2989
	dd sz_buf2d_vox_obj_get_img_h_3g, buf_vox_obj_get_img_h_3g
2815 IgorA 2990
	dd sz_buf2d_vox_obj_draw_1g, buf_vox_obj_draw_1g
2758 IgorA 2991
	dd sz_buf2d_vox_obj_draw_3g, buf_vox_obj_draw_3g
2992
	dd sz_buf2d_vox_obj_draw_3g_scaled, buf_vox_obj_draw_3g_scaled
2993
	dd sz_buf2d_vox_obj_draw_pl, buf_vox_obj_draw_pl
2994
	dd sz_buf2d_vox_obj_draw_pl_scaled, buf_vox_obj_draw_pl_scaled
2995
	dd sz_buf2d_vox_obj_draw_3g_shadows, buf_vox_obj_draw_3g_shadows
1535 IgorA 2996
	dd 0,0
2997
	sz_lib_init db 'lib_init',0
2998
	sz_buf2d_create db 'buf2d_create',0
2999
	sz_buf2d_create_f_img db 'buf2d_create_f_img',0
3000
	sz_buf2d_clear db 'buf2d_clear',0 ;очистка буфера указанным цветом
3001
	sz_buf2d_draw db 'buf2d_draw',0
3002
	sz_buf2d_delete db 'buf2d_delete',0
2136 IgorA 3003
	sz_buf2d_resize db 'buf2d_resize',0
2975 IgorA 3004
	sz_buf2d_rotate db 'buf2d_rotate',0
1535 IgorA 3005
	sz_buf2d_line db 'buf2d_line',0 ;рисование линии
2230 IgorA 3006
	sz_buf2d_line_sm db 'buf2d_line_sm',0 ;рисование сглаженной линии
1642 IgorA 3007
	sz_buf2d_rect_by_size db 'buf2d_rect_by_size',0 ;рисование рамки прямоугольника, 2-я координата задана по размеру
3008
	sz_buf2d_filled_rect_by_size db 'buf2d_filled_rect_by_size',0 ;рисование залитого прямоугольника, 2-я координата задана по размеру
1535 IgorA 3009
	sz_buf2d_circle db 'buf2d_circle',0 ;рисование окружности
3010
	sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 ;сжатие изображения по высоте в 2 раза (размер буфера не меняется)
3011
	sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 ;сжатие изображения по ширине в 2 раза (размер буфера не меняется)
3012
	sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0
3013
	sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0
3014
	sz_buf2d_bit_blt db 'buf2d_bit_blt',0
3015
	sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0
3016
	sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0
1727 IgorA 3017
	sz_buf2d_curve_bezier db 'buf2d_curve_bezier',0
1535 IgorA 3018
	sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0
3019
	sz_buf2d_draw_text db 'buf2d_draw_text',0
3020
	sz_buf2d_crop_color db 'buf2d_crop_color',0
3021
	sz_buf2d_offset_h db 'buf2d_offset_h',0
1684 IgorA 3022
	sz_buf2d_flood_fill db 'buf2d_flood_fill',0
1910 IgorA 3023
	sz_buf2d_set_pixel db 'buf2d_set_pixel',0
2658 IgorA 3024
	sz_buf2d_get_pixel db 'buf2d_get_pixel',0
5389 IgorA 3025
	sz_buf2d_flip_h db 'buf2d_flip_h',0
3040 IgorA 3026
	sz_buf2d_flip_v db 'buf2d_flip_v',0
3105 IgorA 3027
	sz_buf2d_filter_dither db 'buf2d_filter_dither',0
2748 IgorA 3028
	sz_buf2d_vox_brush_create db 'buf2d_vox_brush_create',0
3029
	sz_buf2d_vox_brush_delete db 'buf2d_vox_brush_delete',0
2758 IgorA 3030
	sz_buf2d_vox_obj_get_img_w_3g db 'buf2d_vox_obj_get_img_w_3g',0
3031
	sz_buf2d_vox_obj_get_img_h_3g db 'buf2d_vox_obj_get_img_h_3g',0
2815 IgorA 3032
	sz_buf2d_vox_obj_draw_1g db 'buf2d_vox_obj_draw_1g',0
2758 IgorA 3033
	sz_buf2d_vox_obj_draw_3g db 'buf2d_vox_obj_draw_3g',0
3034
	sz_buf2d_vox_obj_draw_3g_scaled db 'buf2d_vox_obj_draw_3g_scaled',0
3035
	sz_buf2d_vox_obj_draw_pl db 'buf2d_vox_obj_draw_pl',0
3036
	sz_buf2d_vox_obj_draw_pl_scaled db 'buf2d_vox_obj_draw_pl_scaled',0
3037
	sz_buf2d_vox_obj_draw_3g_shadows db 'buf2d_vox_obj_draw_3g_shadows',0