format MS COFF
public EXPORTS
section '.flat' code readable align 16

include '../../../../macros.inc'
include '../../../../proc32.inc'

;-----------------------------------------------------------------------------
mem.alloc   dd ? ;äã­ªæ¨ï ¤«ï ¢ë¤¥«¥­¨ï ¯ ¬ïâ¨
mem.free    dd ? ;äã­ªæ¨ï ¤«ï ®á¢®¡®¦¤¥­¨ï ¯ ¬ïâ¨
mem.realloc dd ? ;äã­ªæ¨ï ¤«ï ¯¥à¥à á¯à¥¤¥«¥­¨ï ¯ ¬ïâ¨
dll.load    dd ?

BUF_STRUCT_SIZE equ 21
buf2d_data equ dword[edi] ;¤ ­­ë¥ ¡ãä¥à  ¨§®¡à ¦¥­¨ï
buf2d_w equ dword[edi+8] ;è¨à¨­  ¡ãä¥à 
buf2d_h equ dword[edi+12] ;¢ëá®â  ¡ãä¥à 
buf2d_l equ word[edi+4]
buf2d_t equ word[edi+6] ;®âáâ㯠ᢥàåã
buf2d_size_lt equ dword[edi+4] ;®âáâ㯠᫥¢  ¨ á¯à ¢  ¤«ï ¡ãä¥à 
buf2d_color equ dword[edi+16] ;梥â ä®­  ¡ãä¥à 
buf2d_bits equ byte[edi+20] ;ª®«¨ç¥á⢮ ¡¨â ¢ 1-© â®çª¥ ¨§®¡à ¦¥­¨ï

struct buf_2d_header
	img_data dd ?
	left dw ? ;+4 left
	top dw ? ;+6 top
	size_x dd ? ;+8 w
	size_y dd ? ;+12 h
	color dd ? ;+16 color
	bit_pp db ? ;+21 bit in pixel
ends

macro swap v1, v2 {
  push v1
  push v2
  pop v1
  pop v2
}

;ä« £¨, ¤«ï ä㭪樨 ®¡à¥§ ­¨ï ¡ãä¥à 
BUF2D_OPT_CROP_TOP equ 1 ;®¡à¥§ª  ᢥàåã
BUF2D_OPT_CROP_LEFT equ 2 ;®¡à¥§ª  á«¥¢ 
BUF2D_OPT_CROP_BOTTOM equ 4 ;®¡à¥§ª  á­¨§ã
BUF2D_OPT_CROP_RIGHT equ 8 ;®¡à¥§ª  á¯à ¢ 
BUF2D_BIT_OPT_CROP_TOP equ 0
BUF2D_BIT_OPT_CROP_LEFT equ 1
BUF2D_BIT_OPT_CROP_BOTTOM equ 2
BUF2D_BIT_OPT_CROP_RIGHT equ 3

;input:
; eax = 㪠§ â¥«ì ­  äã­ªæ¨î ¢ë¤¥«¥­¨ï ¯ ¬ïâ¨
; ebx = ... ®á¢®¡®¦¤¥­¨ï ¯ ¬ïâ¨
; ecx = ... ¯¥à¥à á¯à¥¤¥«¥­¨ï ¯ ¬ïâ¨
; edx = ... § £à㧪¨ ¡¨¡«¨®â¥ª¨ (¯®ª  ­¥ ¨á¯®«ì§ã¥âáï)
align 16
lib_init:
	mov dword[mem.alloc], eax
	mov dword[mem.free], ebx
	mov dword[mem.realloc], ecx
	mov dword[dll.load], edx
	ret

;input:
; ebx = coord x
; ecx = coord y
; edx = pixel color
; edi = pointer to buffer struct
align 4
draw_pixel:
	;cmp buf2d_bits,24
	;jne @f
	bt ebx,31
	jc @f
	bt ecx,31
	jc @f
	cmp ebx,buf2d_w
	jge @f
	cmp ecx,buf2d_h
	jge @f
	push esi
		mov esi,buf2d_w ;size x
		imul esi,ecx ;size_x*y
		add esi,ebx	 ;size_x*y+x
		lea esi,[esi+esi*2] ;(size_x*y+x)*3
		add esi,buf2d_data  ;ptr+(size_x*y+x)*3
 
		mov word[esi],dx ;copy pixel color
		ror edx,16
		mov byte[esi+2],dl
		ror edx,16
	pop esi
	@@:
	ret
;endp

;ᮧ¤ ­¨¥ ¡ãä¥à 
align 4
proc buf_create, buf_struc:dword
	pushad
	mov edi,dword[buf_struc]
	mov ecx,buf2d_w
	mov ebx,buf2d_h
	imul ecx,ebx
	cmp buf2d_bits,24
	jne @f
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
		;;;inc ecx ;§ ¯ á­®© ¡ ©â ¢ ª®­æ¥ ¡ãä¥à , çâ®-¡ë ­¥ £«î稫¨ ­¥ª®â®àë¥ ä㭪樨 ­  ¨§®¡à ¦¥­¨ïå ªà â­ëå 4Š
	@@:
	cmp buf2d_bits,32
	jne @f
		shl ecx,2 ; 32 bit = 4
	@@:
	invoke mem.alloc,ecx
	mov buf2d_data,eax

	stdcall buf_clear,edi,buf2d_color ;®ç¨á⪠ ¡ãä¥à  ä®­®¢ë¬ 梥⮬
	popad
	ret
endp

;ᮧ¤ ­¨¥ ¡ãä¥à  ­  ®á­®¢¥ ¨§®¡à ¦¥­¨ï rgb
align 4
proc buf_create_f_img, buf_struc:dword, rgb_data:dword
	pushad
	mov edi,dword[buf_struc]
	mov ecx,buf2d_w
	mov ebx,buf2d_h
	imul ecx,ebx
	cmp buf2d_bits,24
	jne @f
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
		;;;inc ecx ;§ ¯ á­®© ¡ ©â ¢ ª®­æ¥ ¡ãä¥à , çâ®-¡ë ­¥ £«î稫¨ ­¥ª®â®àë¥ ä㭪樨 ­  ¨§®¡à ¦¥­¨ïå ªà â­ëå 4Š
	@@:
	cmp buf2d_bits,32
	jne @f
		shl ecx,2 ; 32 bit = 4
	@@:
	invoke mem.alloc,ecx
	mov buf2d_data,eax

	cmp buf2d_bits,24
	jne @f
		cld
		mov esi,[rgb_data]
		mov edi,eax ;eax=buf2d_data
		rep movsb ;ª®¯¨à㥬 ¡¨âë ¨§®¡à ¦¥­¨ï ¢ ¡ãä¥à
		jmp .end_create
	@@:
		stdcall buf_clear,edi,buf2d_color ;®ç¨á⪠ ¡ãä¥à  ä®­®¢ë¬ 梥⮬
	.end_create:
	popad
	ret
endp

align 4
proc buf_clear, buf_struc:dword, color:dword ;®ç¨á⪠ ¡ãä¥à  § ¤ ­ë¬ 梥⮬
	pushad
	mov edi,dword[buf_struc]

	mov ecx,buf2d_w
	mov ebx,buf2d_h
	imul ecx,ebx

	cld

	cmp buf2d_bits,8
	jne .end_clear_8
		mov edi,buf2d_data
		mov al,byte[color]
		rep stosb
		jmp .end_clear_32
	.end_clear_8:

	cmp buf2d_bits,24
	jne .end_clear_24
		mov edi,buf2d_data
		mov eax,dword[color]
		mov ebx,eax
		shr ebx,16
		@@:
			stosw
			mov byte[edi],bl
			inc edi
			loop @b
		jmp .end_clear_32
	.end_clear_24:

	cmp buf2d_bits,32
	jne .end_clear_32
		mov edi,buf2d_data
		mov eax,dword[color]
		rep stosd
		;jmp .end_clear_32
	.end_clear_32:
	popad
	ret
endp

;äã­ªæ¨ï ¤«ï ®¡à¥§ ­¨ï ¡ãä¥à®¢ 8 ¨ 24 ¡¨â­ëå, ¯® § ¤ ­®¬ã 梥âã.
;¯ à ¬¥âà opt § ¤ ¥âáï ª®¬¡¨­ æ¨¥© ª®­áâ ­â:
; BUF2D_OPT_CROP_TOP - ®¡à¥§ª  ᢥàåã
; BUF2D_OPT_CROP_LEFT - ®¡à¥§ª  á«¥¢ 
; BUF2D_OPT_CROP_BOTTOM - ®¡à¥§ª  á­¨§ã
; BUF2D_OPT_CROP_RIGHT - ®¡à¥§ª  á¯à ¢ 
align 4
proc buf_crop_color, buf_struc:dword, color:dword, opt:dword
locals
	crop_r dd ?
endl
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .24end_f

	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
	jae .24no_crop_bottom
		mov eax,dword[color]
		mov edx,eax ;ax = colors - r,g
		shr edx,16 ;dl = color - b
		mov ecx,buf2d_h
		cmp ecx,1
		jle .24no_crop_bottom ;¯à®¢¥à塞 ­  á«ãç © ¥á«¨ ¢ëá®â  ¡ãä¥à  1 ¯¨ªá¥«ì
		mov ebx,buf2d_w
		imul ecx,ebx
		lea esi,[ecx+ecx*2] ;esi=3*ecx
		add esi,buf2d_data
		cld
		@@:
			sub esi,3
			cmp word[esi],ax
			jne @f
			cmp byte[esi+2],dl
			jne @f
			loop @b
		@@:
		lea ebx,[ebx+ebx*2]
		xor edx,edx
		mov eax,buf2d_h
		imul eax,ebx
		add eax,buf2d_data ;eax - 㪠§ â¥«ì ­  ª®­¥æ ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		@@:
			add esi,ebx
			cmp esi,eax
			jge @f
			inc edx ;¢ëç¨á«ï¥¬ ç¨á«® ¯®«­ëå áâப ¤«ï ®¡à¥§ ­¨ï
			loop @b
		@@:
		cmp edx,0
		je .24no_crop_bottom
			cmp edx,buf2d_h
			jge .24no_crop_bottom ;çâ®-¡ë ­¥ ¯®«ãç¨âì ¯ãá⮩ ¡ãä¥à
			sub buf2d_h,edx ;㬥­ìè ¥¬ ¢ëá®âã ¡ãä¥à 
			mov ecx,buf2d_h
			imul ecx,ebx ;ecx = ­®¢ë© à §¬¥à ¨§®¡à ¦¥­¨ï
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.24no_crop_bottom:

	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
	jae .24no_crop_top
		mov eax,dword[color]
		mov edx,eax ;ax = colors - r,g
		shr edx,16 ;dl = color - b
		mov esi,buf2d_data
		mov ecx,buf2d_h
		cmp ecx,1
		jle .24no_crop_top ;¯à®¢¥à塞 ­  á«ãç © ¥á«¨ ¢ëá®â  ¡ãä¥à  1 ¯¨ªá¥«ì
		dec ecx ;¯à¨ ®¡à¥§ ­¨¨ ¤®«¦­  ®áâ âìáï ¬¨­¨¬ã¬ 1-­  áâப  ¯¨ªá¥«¥©
		mov ebx,buf2d_w
		imul ecx,ebx
		cld
		@@:
			cmp word[esi],ax
			jne @f
			cmp byte[esi+2],dl
			jne @f
			add esi,3
			loop @b
		@@:
		lea ebx,[ebx+ebx*2]
		xor edx,edx
		@@:
			sub esi,ebx
			cmp esi,buf2d_data
			jl @f
			inc edx ;¢ëç¨á«ï¥¬ ç¨á«® ¯®«­ëå áâப ¤«ï ®¡à¥§ ­¨ï
			loop @b
		@@:
		cmp edx,0
		je .24no_crop_top
			xor eax,eax
			sub eax,edx
			mov ebx,buf2d_h
			sub ebx,edx
			stdcall buf_offset_h, edi, eax, edx, ebx ;ᤢ¨£ ¥¬ ¨§®¡à ¦¥­¨¥ ¢ ¡ãä¥à¥ ¢¢¥àå (eax<0)
			sub buf2d_h,edx ;㬥­ìè ¥¬ ¢ëá®âã ¡ãä¥à 
			mov ecx,buf2d_h
			add buf2d_t,dx ;ᤢ¨£ ¥¬ ®âáâ㯠¢­¨§, ­  ç¨á«® ®¡à¥§ ­­ëå áâப
			mov ebx,buf2d_w
			imul ecx,ebx
			lea ecx,[ecx+ecx*2]
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.24no_crop_top:

	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
	jae .24no_crop_right
		mov eax,dword[color]
		mov edx,eax ;ax = colors - r,g
		shr edx,16 ;dl = color - b
		mov ebx,buf2d_w
		cmp ebx,1
		jle .24no_crop_right ;­  á«ãç © ¥á«¨ è¨à¨­  ¡ãä¥à  1 ¯¨ªá¥«ì
		lea ebx,[ebx+ebx*2]
		mov esi,ebx
		imul esi,buf2d_h
		add esi,buf2d_data ;esi - 㪠§ â¥«ì ­  ª®­¥æ ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		mov dword[crop_r],0
		cld
		.24found_beg_right:
		sub esi,3 ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢«¥¢®
		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			cmp word[esi],ax
			jne .24found_right
			cmp byte[esi+2],dl
			jne .24found_right
			sub esi,ebx ;¯à룠¥¬ ­  ¢¥àå­îî áâபã
			loop @b
		inc dword[crop_r]

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp dword[crop_r],ecx
		jge .24found_right

		sub esi,3 ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢«¥¢®
		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			add esi,ebx ;¯à룠¥¬ ­  ­¨¦­îî áâபã
			cmp word[esi],ax
			jne .24found_right
			cmp byte[esi+2],dl
			jne .24found_right
			loop @b
		inc dword[crop_r]

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp dword[crop_r],ecx
		jl .24found_beg_right

		.24found_right:
		cmp dword[crop_r],0
		je .24no_crop_right
			mov ecx,buf2d_w
			sub ecx,dword[crop_r]
			stdcall img_rgb_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;®¡à¥§ ¥¬ ¡ãä¥à, ¯® ­®¢®¬ã à §¬¥àã
			mov buf2d_w,ecx ;áâ ¢¨¬ ­®¢ãî è¨à¨­ã ¤«ï ¡ãä¥à 
			mov ebx,buf2d_h
			imul ecx,ebx
			lea ecx,[ecx+ecx*2]
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.24no_crop_right:

	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
	jae .24no_crop_left
		mov eax,dword[color]
		mov edx,eax ;ax = colors - r,g
		shr edx,16 ;dl = color - b
		mov ebx,buf2d_w
		cmp ebx,1
		jle .24no_crop_left ;­  á«ãç © ¥á«¨ è¨à¨­  ¡ãä¥à  1 ¯¨ªá¥«ì
		lea ebx,[ebx+ebx*2]
		mov esi,buf2d_data ;esi - 㪠§ â¥«ì ­  ­ ç®«® ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		mov dword[crop_r],0
		cld
		.24found_beg_left:

		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			cmp word[esi],ax
			jne .24found_left
			cmp byte[esi+2],dl
			jne .24found_left
			add esi,ebx ;¯à룠¥¬ ­  ­¨¦­îî áâபã
			loop @b
		inc dword[crop_r]
		add esi,3 ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢¯à ¢®

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp dword[crop_r],ecx
		jge .24found_left

		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			sub esi,ebx ;¯à룠¥¬ ­  ¢¥àå­îî áâபã
			cmp word[esi],ax
			jne .24found_left
			cmp byte[esi+2],dl
			jne .24found_left
			loop @b
		inc dword[crop_r]
		add esi,3 ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢¯à ¢®

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp dword[crop_r],ecx
		jl .24found_beg_left

		.24found_left:
		cmp dword[crop_r],0
		je .24no_crop_left
			mov ecx,buf2d_w
			sub ecx,dword[crop_r]
			stdcall img_rgb_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;®¡à¥§ ¥¬ ¡ãä¥à, ¯® ­®¢®¬ã à §¬¥àã
			mov buf2d_w,ecx ;áâ ¢¨¬ ­®¢ãî è¨à¨­ã ¤«ï ¡ãä¥à 
			mov ebx,buf2d_h
			imul ecx,ebx
			lea ecx,[ecx+ecx*2]
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
			mov eax,dword[crop_r]
			add buf2d_l,ax
	.24no_crop_left:

	.24end_f:


	cmp buf2d_bits,8
	jne .8end_f

	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
	jae .8no_crop_bottom
		mov eax,dword[color]
		mov esi,buf2d_data
		mov ecx,buf2d_h
		cmp ecx,1
		jle .8no_crop_bottom ;¯à®¢¥à塞 ­  á«ãç © ¥á«¨ ¢ëá®â  ¡ãä¥à  1 ¯¨ªá¥«ì
		mov ebx,buf2d_w
		imul ecx,ebx
		mov esi,ecx
		add esi,buf2d_data
		cld
		@@:
			dec esi
			cmp byte[esi],al
			jne @f
			loop @b
		@@:
		xor edx,edx
		mov eax,buf2d_h
		imul eax,ebx
		add eax,buf2d_data ;eax - 㪠§ â¥«ì ­  ª®­¥æ ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		@@:
			add esi,ebx
			cmp esi,eax
			jge @f
			inc edx
			loop @b
		@@:
		cmp edx,0
		je .8no_crop_bottom
			cmp edx,buf2d_h
			jge .8no_crop_bottom ;çâ®-¡ë ­¥ ¯®«ãç¨âì ¯ãá⮩ ¡ãä¥à
			sub buf2d_h,edx ;㬥­ìè ¥¬ ¢ëá®âã ¡ãä¥à 
			mov ecx,buf2d_h
			imul ecx,ebx ;ecx = ­®¢ë© à §¬¥à ¨§®¡à ¦¥­¨ï
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.8no_crop_bottom:

	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
	jae .8no_crop_top
		mov eax,dword[color]
		mov esi,buf2d_data
		mov ecx,buf2d_h
		cmp ecx,1
		jle .8no_crop_top ;¯à®¢¥à塞 ­  á«ãç © ¥á«¨ ¢ëá®â  ¡ãä¥à  1 ¯¨ªá¥«ì
		dec ecx ;¯à¨ ®¡à¥§ ­¨¨ ¤®«¦­  ®áâ âìáï ¬¨­¨¬ã¬ 1-­  áâப  ¯¨ªá¥«¥©
		mov ebx,buf2d_w
		imul ecx,ebx
		cld
		@@:
			cmp byte[esi],al
			jne @f
			inc esi
			loop @b
		@@:
		xor edx,edx
		@@:
			sub esi,ebx
			cmp esi,buf2d_data
			jl @f
			inc edx
			loop @b
		@@:
		cmp edx,0
		je .8no_crop_top
			xor eax,eax
			sub eax,edx
			mov ebx,buf2d_h
			sub ebx,edx
			stdcall buf_offset_h, edi, eax, edx, ebx
			mov ecx,buf2d_h
			sub ecx,edx
			mov buf2d_h,ecx ;㬥­ìè ¥¬ ¢ëá®âã ¡ãä¥à 
			add buf2d_t,dx ;ᤢ¨£ ¥¬ ®âáâ㯠¢­¨§, ­  ç¨á«® ®¡à¥§ ­­ëå áâப
			mov ebx,buf2d_w
			imul ecx,ebx
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.8no_crop_top:

	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
	jae .8no_crop_right
		mov eax,dword[color]
		mov ebx,buf2d_w
		cmp ebx,1
		jle .8no_crop_right ;­  á«ãç © ¥á«¨ è¨à¨­  ¡ãä¥à  1 ¯¨ªá¥«ì
		mov esi,ebx
		imul esi,buf2d_h
		add esi,buf2d_data ;esi - 㪠§ â¥«ì ­  ª®­¥æ ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		xor edx,edx
		cld

		.8found_beg:
		dec esi ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢«¥¢®
		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			cmp byte[esi],al
			jne .8found
			sub esi,ebx ;¯à룠¥¬ ­  ¢¥àå­îî áâபã
			loop @b
		inc edx
		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp edx,ecx
		jge .8found

		dec esi ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢«¥¢®
		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			add esi,ebx ;¯à룠¥¬ ­  ­¨¦­îî áâபã
			cmp byte[esi],al
			jne .8found
			loop @b
		inc edx

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp edx,ecx
		jl .8found_beg

		.8found:
		cmp edx,0
		je .8no_crop_right
			mov ecx,buf2d_w
			sub ecx,edx
			stdcall img_gray_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;®¡à¥§ ¥¬ ¡ãä¥à, ¯® ­®¢®¬ã à §¬¥àã
			mov buf2d_w,ecx ;áâ ¢¨¬ ­®¢ãî è¨à¨­ã ¤«ï ¡ãä¥à 
			mov ebx,buf2d_h
			imul ecx,ebx
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.8no_crop_right:

	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
	jae .8no_crop_left
		mov eax,dword[color]
		mov ebx,buf2d_w
		cmp ebx,1
		jle .8no_crop_left ;­  á«ãç © ¥á«¨ è¨à¨­  ¡ãä¥à  1 ¯¨ªá¥«ì
		mov esi,buf2d_data ;esi - 㪠§ â¥«ì ­  ­ ç®«® ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		mov edx,0
		cld
		.8found_beg_left:

		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			cmp word[esi],ax
			jne .8found_left
			add esi,ebx ;¯à룠¥¬ ­  ­¨¦­îî áâபã
			loop @b
		inc edx
		inc esi ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢¯à ¢®

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp edx,ecx
		jge .8found_left

		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			sub esi,ebx ;¯à룠¥¬ ­  ¢¥àå­îî áâபã
			cmp word[esi],ax
			jne .8found_left
			loop @b
		inc edx
		inc esi ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢¯à ¢®

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp edx,ecx
		jl .8found_beg_left

		.8found_left:
		cmp edx,0
		je .8no_crop_left
			mov ecx,buf2d_w
			sub ecx,edx
			stdcall img_gray_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;®¡à¥§ ¥¬ ¡ãä¥à, ¯® ­®¢®¬ã à §¬¥àã
			mov buf2d_w,ecx ;áâ ¢¨¬ ­®¢ãî è¨à¨­ã ¤«ï ¡ãä¥à 
			mov ebx,buf2d_h
			imul ecx,ebx
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
			mov eax,edx
			add buf2d_l,ax
	.8no_crop_left:

	.8end_f:

	popad
	ret
endp

;®¡à¥§ ¥¬ 梥⭮¥ ¨§®¡à ¦¥­¨¥ á ¯à ¢®© áâ®à®­ë
;input:
;data_rgb - pointer to rgb data
;size_w_old - width img in pixels
;size_w_new - new width img in pixels
;size_h - height img in pixels
align 4
proc img_rgb_crop_r, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
	pushad
	mov eax, dword[size_w_old]
	lea eax, dword[eax+eax*2] ;eax = width(old) * 3(rgb)
	mov ebx, dword[size_w_new]
	lea ebx, dword[ebx+ebx*2] ;ebx = width(new) * 3(rgb)
	mov edx, dword[size_h]
	mov edi, dword[data_rgb] ;edi - ¯®«ã砥⠤ ­­ë¥
	mov esi, edi
	add edi, ebx
	add esi, eax
	cld
	@@:
		dec edx ;㬥­ìè ¥¬ áç¥â稪 ®áâ ¢è¨åáï áâப ­  1
		cmp edx,0
		jle @f
		mov ecx, ebx
		rep movsb ;¯¥à¥­®á (ª®¯¨à®¢ ­¨¥) áâப¨ ¯¨ªá¥«¥©
		add esi,eax ;¯¥à¥å®¤ ­  ­®¢ãî áâà®çªã ¨§®¡à ¦¥­¨ï
		sub esi,ebx
		jmp @b
	@@:
	popad
	ret
endp

;®¡à¥§ ¥¬ á¥à®¥ ¨§®¡à ¦¥­¨¥ á ¯à ¢®© áâ®à®­ë
;input:
;data_gray - pointer to gray data
;size_w_old - width img in pixels
;size_w_new - new width img in pixels
;size_h - height img in pixels
align 4
proc img_gray_crop_r, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
	pushad
	mov eax, dword[size_w_old]
	mov ebx, dword[size_w_new]
	mov edx, dword[size_h]
	mov edi, dword[data_gray] ;edi - ¯®«ã砥⠤ ­­ë¥
	mov esi, edi
	add edi, ebx
	add esi, eax
	cld
	@@:
		dec edx ;㬥­ìè ¥¬ áç¥â稪 ®áâ ¢è¨åáï áâப ­  1
		cmp edx,0
		jle @f
		mov ecx, ebx
		rep movsb ;¯¥à¥­®á (ª®¯¨à®¢ ­¨¥) áâப¨ ¯¨ªá¥«¥©
		add esi,eax ;¯¥à¥å®¤ ­  ­®¢ãî áâà®çªã ¨§®¡à ¦¥­¨ï
		sub esi,ebx
		jmp @b
	@@:
	popad
	ret
endp

;®¡à¥§ ¥¬ 梥⭮¥ ¨§®¡à ¦¥­¨¥ á «¥¢®© áâ®à®­ë
;input:
;data_rgb - pointer to rgb data
;size_w_old - width img in pixels
;size_w_new - new width img in pixels
;size_h - height img in pixels
align 4
proc img_rgb_crop_l, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
	pushad
	mov edi,dword[data_rgb]
	mov esi,edi
	mov eax,dword[size_w_old]
	mov ebx,dword[size_w_new]
	cmp eax,ebx
	jle .end_f ;áâ àë© à §¬¥à ¨§®¡à ¦¥­¨ï ­¥ ¬®¦¥â ¡ëâì ¬¥­ìè¥ ­®¢®£® (¯à¨ ãá«®¢¨¨ ®¡à¥§ ­¨ï ª à⨭ª¨)
		lea eax,[eax+eax*2]
		lea ebx,[ebx+ebx*2]
		sub eax,ebx
		mov edx,dword[size_h] ;¢ëá®â  ¨§®¡à ¦¥­¨ï
		cld
		@@:
			add esi,eax
			mov ecx,ebx
			rep movsb
			dec edx
			cmp edx,0
			jg @b
	.end_f:
	popad
	ret
endp

;®¡à¥§ ¥¬ á¥à®¥ ¨§®¡à ¦¥­¨¥ á «¥¢®© áâ®à®­ë
;input:
;data_gray - pointer to gray data
;size_w_old - width img in pixels
;size_w_new - new width img in pixels
;size_h - height img in pixels
align 4
proc img_gray_crop_l, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
	pushad
	mov edi,dword[data_gray]
	mov esi,edi
	mov eax,dword[size_w_old]
	mov ebx,dword[size_w_new]
	cmp eax,ebx
	jle .end_f ;áâ àë© à §¬¥à ¨§®¡à ¦¥­¨ï ­¥ ¬®¦¥â ¡ëâì ¬¥­ìè¥ ­®¢®£® (¯à¨ ãá«®¢¨¨ ®¡à¥§ ­¨ï ª à⨭ª¨)
		sub eax,ebx
		mov edx,dword[size_h] ;¢ëá®â  ¨§®¡à ¦¥­¨ï
		cld
		@@:
			add esi,eax
			mov ecx,ebx
			rep movsb
			dec edx
			cmp edx,0
			jg @b
	.end_f:
	popad
	ret
endp

;hoffs - ª®««¨ç¥á⢮ ¯¨ªá¥«¥© ­  ª®âàë¥ ¯®¤­¨¬ ¥âáï/®¯ã᪠¥âáï ¨§®¡à ¦¥­¨¥
;img_t - ¢ëá®â , á ª®â®à®© ­ ç¨­ ¥âáï ¤¢¨£ îé ïáï ç áâì ¨§®¡à ¦¥­¨ï
align 4
proc buf_offset_h, buf_struc:dword, hoffs:dword, img_t:dword, img_h:dword ;ᤢ¨£ ¥â ¨§®¡à ¦¥­¨¥ ¯® ¢ëá®â¥
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .end_move_24

	mov eax,[hoffs]
	cmp eax,0
	je .end_move_24
		mov ebx,buf2d_w
		mov edx,dword[img_t]
			mov ecx,dword[img_h] ;ecx - ¢ëá®â  ᤢ¨£ ¥¬ëå ¤ ­­ëå
			cmp ecx,buf2d_h
			jge .end_f ;®è¨¡®ç­®¥ ãá«®¢¨¥, ¢ëá®â  ¨§®¡à ¦¥­¨ï ¬¥­ìè¥ ç¥¬ ¢ëá®â  ᤢ¨£ ¥¬®£® ¨§®¡à ¦¥­¨ï
			imul ecx,ebx ;ecx - ª®««¨ç¥á⢮ ¯¨ªá¥«¥© ¢ ᤢ¨£ ¥¬ëå ¤ ­­ëå
			lea ecx,[ecx+ecx*2]
		imul ebx,edx
		lea ebx,[ebx+ebx*2]
		mov esi,buf2d_data
		add esi,ebx

		add edx,eax ;edx = img_t+hoffs (hoffs<0)
		mov ebx,buf2d_w
		imul ebx,edx
		lea ebx,[ebx+ebx*2]
		mov edi,buf2d_data ;¯®§¨æ¨ï, ªã¤  ¡ã¤¥â ¤¢¨£ âìáï ¨§®¡à ¦¥­¨¥
		add edi,ebx

		cmp eax,0
		jg .move_down_24
			;¤¢¨£ ¥¬ ¨§®¡à ¦¥­¨¥ ¢¢¥àå
			cld
			rep movsb
			jmp .end_f
		.move_down_24:
			;¤¢¨£ ¥¬ ¨§®¡à ¦¥­¨¥ ¢­¨§
			add esi,ecx
			dec esi
			add edi,ecx
			dec edi
			std
			rep movsb
			jmp .end_f
	.end_move_24:

;stdcall print_err,sz_buf2d_offset_h,txt_err_n24b

	cmp buf2d_bits,8
	jne .end_move_8

	mov eax,[hoffs]
	cmp eax,0
	je .end_move_8
		;¤¢¨£ ¥¬ ¨§®¡à ¦¥­¨¥ ¢¢¥àå
		mov ebx,buf2d_w
		mov edx,dword[img_t]
			mov ecx,dword[img_h] ;ecx - ¢ëá®â  ᤢ¨£ ¥¬ëå ¤ ­­ëå
			cmp ecx,buf2d_h
			jge .end_f ;®è¨¡®ç­®¥ ãá«®¢¨¥, ¢ëá®â  ¨§®¡à ¦¥­¨ï ¬¥­ìè¥ ç¥¬ ¢ëá®â  ᤢ¨£ ¥¬®£® ¨§®¡à ¦¥­¨ï
			imul ecx,ebx ;ecx - ª®««¨ç¥á⢮ ¯¨ªá¥«¥© ¢ ᤢ¨£ ¥¬ëå ¤ ­­ëå
		imul ebx,edx
		mov esi,buf2d_data
		add esi,ebx

		add edx,eax ;edx = img_t+hoffs (hoffs<0)
		mov ebx,buf2d_w
		imul ebx,edx
		mov edi,buf2d_data ;¯®§¨æ¨ï, ªã¤  ¡ã¤¥â ¤¢¨£ âìáï ¨§®¡à ¦¥­¨¥
		add edi,ebx

		cmp eax,0
		jg .move_down_8
			cld
			rep movsb
			jmp .end_f
		.move_down_8:
			;¤¢¨£ ¥¬ ¨§®¡à ¦¥­¨¥ ¢­¨§
			add esi,ecx
			dec esi
			add edi,ecx
			dec edi
			std
			rep movsb
			jmp .end_f
	.end_move_8:

	.end_f:
	popad
	ret
endp


align 4
proc buf_draw_buf, buf_struc:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .error
		mov eax,7
		mov ebx,buf2d_data

		mov ecx,buf2d_w
		ror ecx,16
		mov edx,buf2d_h
		mov cx,dx

		mov edx,buf2d_size_lt
		ror edx,16
		int 0x40
		jmp .end_draw_24
	.error:
		stdcall print_err,sz_buf2d_draw,txt_err_n24b
	.end_draw_24:
	popad
	ret
endp

align 4
proc buf_delete, buf_struc:dword
	push edi
	mov edi,dword[buf_struc]
	invoke mem.free,buf2d_data
	pop edi
	ret
endp

align 4
proc buf_line_brs, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
locals
	loc_1 dd ?
	loc_2 dd ?
	napravl db ?
endl
	pushad
		mov edx,dword[color]

		mov eax,dword[coord_x1]
		sub eax,dword[coord_x0]
		bt eax,31
		jae @f
			neg eax
			inc eax
		@@:
		mov ebx,dword[coord_y1]
		sub ebx,dword[coord_y0]
		bt ebx,31
		jae @f
			neg ebx
			inc ebx
		@@:

		mov [napravl],byte 0 ;bool steep=false
		cmp eax,ebx
		jle @f
			mov [napravl],byte 1 ;bool steep=true
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
		@@:
		mov eax,dword[coord_y0] ;x0
		cmp eax,dword[coord_y1] ;if(x0>x1)
		jle @f
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
		@@:

; int deltax esi
; int deltay edi
; int error  ebp-6
; int ystep  ebp-8

		mov eax,dword[coord_y0]
		mov esi,dword[coord_y1]
		sub esi,eax ;deltax = y1-y0
		mov ebx,esi
		shr ebx,1
		mov [loc_1],ebx ;error = deltax/2

		mov eax,dword[coord_x0]
		mov edi,dword[coord_x1]
		mov [loc_2],dword -1 ;ystep = -1
		cmp eax,edi ;if (x0<x1) ystep = 1;
		jge @f
			mov [loc_2],dword 1 ;ystep = 1
		@@:
		sub edi,eax ;x1-x0

		bts edi,31
		jae @f
			neg edi
			inc edi
		@@:
		and edi,0x7fffffff ;deltay = abs(x1-x0)

		mov eax,edi
		mov edi,[buf_struc]
		cmp buf2d_bits,24
		jne .coord_end

		cmp [napravl],0
		jne .coord_yx
			mov ebx,dword[coord_x0]
			mov ecx,dword[coord_y0]

			@@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
				cmp ecx,dword[coord_y1]
				jg @f ;jge ???
				call draw_pixel

				sub dword[loc_1],eax ;error -= deltay
				cmp dword[loc_1],0 ;if(error<0)
				jge .if0
					add ebx,[loc_2] ;y += ystep
					add [loc_1],esi ;error += deltax
				.if0:
				inc ecx
				jmp @b
			@@:
			jmp .coord_end
		.coord_yx:
			mov ebx,dword[coord_y0]
			mov ecx,dword[coord_x0]

			@@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
				cmp ebx,dword[coord_y1]
				jg @f ;jge ???
				call draw_pixel

				sub dword[loc_1],eax ;error -= deltay
				cmp dword[loc_1],0 ;if(error<0)
				jge .if1
					add ecx,[loc_2] ;y += ystep
					add [loc_1],esi ;error += deltax
				.if1:
				inc ebx
				jmp @b
			@@:
	.coord_end:
	popad
	ret
endp

;à¨á®¢ ­¨¥ £®à¨§®­â «ì­®© «¨­¨¨, ¯®â®¬ã ­¥â ¯ à ¬¥âà  coord_y1
align 4
proc buf_line_h, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, color:dword
	pushad
		mov edx,dword[color]

		mov eax,edi
		mov edi,[buf_struc]
		cmp buf2d_bits,24
		jne @f

		mov ebx,dword[coord_x0]
		mov ecx,dword[coord_y0]
		mov esi,dword[coord_x1]
		
		@@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
			call draw_pixel
			inc ebx
			cmp ebx,esi
			jge @f
			jmp @b
		@@:
	popad
	ret
endp

align 4
proc buf_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
pushad
	mov edi,[buf_struc]
	cmp buf2d_bits,24
	jne .coord_end

		mov eax,[coord_x]
		mov ebx,[coord_y]
		mov ecx,[w]
		cmp ecx,1
		jl .coord_end
		add ecx,eax
		dec ecx
		mov edx,[h]
		cmp edx,1
		jl .coord_end

		add edx,ebx
		dec edx
		mov esi,dword[color]
		stdcall buf_line_h, edi, eax, ebx, ecx, esi ;«¨­¨ï -
		stdcall buf_line_brs, edi, eax, ebx, eax, edx, esi ;«¨­¨ï |
		stdcall buf_line_h, edi, eax, edx, ecx, esi ;«¨­¨ï -
		stdcall buf_line_brs, edi, ecx, ebx, ecx, edx, esi ;«¨­¨ï |
	.coord_end:
popad
	ret
endp

align 4
proc buf_filled_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
pushad
	mov edi,[buf_struc]
	cmp buf2d_bits,24
	jne .coord_end
		mov eax,[coord_x]
		mov ebx,[coord_y]
		mov edx,[w]
		add edx,eax
		mov ecx,[h]
		mov esi,dword[color]
		cld
		@@:
			stdcall buf_line_h, edi, eax, ebx, edx, esi ;«¨­¨ï -
			inc ebx
			loop @b
	.coord_end:
popad
	ret
endp

align 4
proc buf_circle, buf_struc:dword, coord_x:dword, coord_y:dword, r:dword, color:dword
locals
	po_x dd ?
	po_y dd ?
endl
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .error
		mov edx,dword[color]

		finit
		fild dword[coord_x]
		fild dword[coord_y]
		fild dword[r]
		fldz ;px=0
		fld st1 ;py=r

		fldpi
		fmul st0,st3
		fistp dword[po_x]
		mov esi,dword[po_x] ;esi=pi*r
		shl esi,1 ;esi=2*pi*r

		;st0 = py
		;st1 = px
		;st2 = r
		;st3 = y
		;st4 = x

		@@:
			;Point(px + x, y - py)
			fld st1 ;st0=px
			fadd st0,st5 ;st0=px+x
			fistp dword[po_x]
			mov ebx,dword[po_x]
			fld st3 ;st0=y
			fsub st0,st1 ;st0=y-py
			fistp dword[po_y]
			mov ecx,dword[po_y]
			call draw_pixel
			;px += py/r
			fld st0 ;st0=py
			fdiv st0,st3 ;st0=py/r
			faddp st2,st0 ;st3+=st0
			;py -= px/r
			fld st1 ;st0=px
			fdiv st0,st3 ;st0=px/r
			fsubp st1,st0 ;st2-=st0

			dec esi
			cmp esi,0
			jge @b
		jmp .exit_fun
	.error:
		stdcall print_err,sz_buf2d_circle,txt_err_n24b
	.exit_fun:

	popad
	ret
endp

align 4
proc buf_img_wdiv2, buf_struc:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .end_draw_24
		mov eax,buf2d_w
		mov ecx,buf2d_h
		imul ecx,eax
		stdcall img_rgb24_wdiv2, buf2d_data,ecx
	.end_draw_24:
	popad
	ret
endp

;input:
;data_rgb - pointer to rgb data
;size - count img pixels (size img data / 3(rgb) )
align 4
proc img_rgb24_wdiv2 data_rgb:dword, size:dword
  ;push eax ebx ecx edx
  mov eax,dword[data_rgb]
  mov ecx,dword[size] ;ecx = size
  lea ecx,[ecx+ecx*2]
  cld
  @@: ;§ â¥¬­¥­¨¥ æ¢¥â  ¯¨ªá¥«¥©
		shr byte[eax],1
		inc eax
		loop @b

  mov eax,dword[data_rgb]
  mov ecx,dword[size] ;ecx = size
  shr ecx,1
  @@: ;á«®¦¥­¨¥ 梥⮢ ¯¨ªá¥«¥©
		mov bx,word[eax+3] ;ª®¯¨à㥬 梥â á®á¥¤­¥£® ¯¨ªá¥«ï
		add word[eax],bx
		mov bl,byte[eax+5] ;ª®¯¨à㥬 梥â á®á¥¤­¥£® ¯¨ªá¥«ï
		add byte[eax+2],bl
		add eax,6 ;=2*3
		loop @b

  mov eax,dword[data_rgb]
  add eax,3
  mov ebx,eax
  add ebx,3
  mov ecx,dword[size] ;ecx = size
  shr ecx,1
  dec ecx ;«¨è­¨© ¯¨ªá¥«ì
  @@: ;¯®¤¦ â¨¥ ¯¨ªá¥«¥©
		mov edx,dword[ebx]
		mov word[eax],dx
		shr edx,16
		mov byte[eax+2],dl

		add eax,3
		add ebx,6
		loop @b
  ;pop edx ecx ebx eax
  ret
endp

align 4
proc buf_img_hdiv2, buf_struc:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .end_draw_24
		mov eax,buf2d_w
		mov ecx,buf2d_h
		imul ecx,eax
		stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
	.end_draw_24:
	popad
	ret
endp

;input:
;data_rgb - pointer to rgb data
;size - count img pixels (size img data / 3(rgb) )
;size_w - width img in pixels
align 4
proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword
  ;pushad

  mov eax,dword[data_rgb] ;eax =
  mov ecx,dword[size]	  ;ecx = size
  lea ecx,[ecx+ecx*2]
  cld
  @@: ;§ â¥¬­¥­¨¥ æ¢¥â  ¯¨ªá¥«¥©
    shr byte[eax],1
    inc eax
    loop @b

  mov eax,dword[data_rgb] ;eax =
  mov edi,dword[size_w]
  lea esi,[edi+edi*2] ;esi = width*3(rgb)
  mov ebx,esi
  add ebx,eax
  mov ecx,dword[size]  ;ecx = size
  shr ecx,1
  xor edi,edi
  @@: ;á«®¦¥­¨¥ 梥⮢ ¯¨ªá¥«¥©
    mov dx,word[ebx] ;ª®¯¨à㥬 梥⠭¨¦­¥£® ¯¨ªá¥«ï
    add word[eax],dx
    mov dl,byte[ebx+2] ;ª®¯¨à㥬 梥⠭¨¦­¥£® ¯¨ªá¥«ï
    add byte[eax+2],dl

    add eax,3
    add ebx,3
    inc edi
    cmp edi,dword[size_w]
    jl .old_line
      add eax,esi
      add ebx,esi
      xor edi,edi
    .old_line:
    loop @b


  mov eax,dword[data_rgb] ;eax =
  add eax,esi ;esi = width*3(rgb)
  mov ebx,esi
  add ebx,eax
  mov ecx,dword[size] ;ecx = size
  shr ecx,1
  sub ecx,dword[size_w] ;«¨è­ïï áâப  ¯¨ªá¥«¥©
  xor edi,edi
  @@: ;¯®¤¦ â¨¥ ¯¨ªá¥«¥©
    mov edx,dword[ebx] ;ª®¯¨à㥬 梥⠭¨¦­¥£® ¯¨ªá¥«ï
    mov word[eax],dx
    shr edx,16
    mov byte[eax+2],dl

    add eax,3
    add ebx,3
    inc edi
    cmp edi,dword[size_w]
    jl .old_line_2
      add ebx,esi
      xor edi,edi
    .old_line_2:
    loop @b

  ;popad
  ret
endp

;¯à¥®¡à §®¢ ­¨¥ ¡ãä¥à  ¨§ 24-¡¨â­®£® ¢ 8-¡¨â­ë©
; spectr - ®¯à¥¤¥«ï¥â ª ª®© ᯥªâà ¡à âì ¯à¨ ¯à¥®¡à §®¢ ­¨¨ 0-ᨭ¨©, 1-§¥«¥­ë©, 2-ªà á­ë©
align 4
proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .error
		mov eax,buf2d_w
		mov ecx,buf2d_h
		imul ecx,eax
		mov esi,ecx
		;ebx - ¯ ¬ïâì ¨§ ª®â®à®© ª®¯¨àã¥âáï
		;edx - ¯ ¬ïâì ªã¤  ª®¯¨àã¥âáï
		mov edx,buf2d_data
		mov ebx,edx
		cmp [spectr],3
		jge @f
			add ebx,[spectr]
		@@:
			mov al,byte[ebx]
			mov byte[edx],al
			add ebx,3
			inc edx
			loop @b
		mov buf2d_bits,8
		invoke mem.realloc,buf2d_data,esi ;㬥­ìè ¥¬ ¯ ¬ïâì § ­¨¬ ¥¬ãî ¡ãä¥à®¬
		jmp .end_conv
	.error:
		stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
	.end_conv:
	popad
	ret
endp

;¯à¥®¡à §®¢ ­¨¥ ¡ãä¥à  ¨§ 24-¡¨â­®£® ¢ 32-¡¨â­ë©
align 4
proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .error1
		mov ecx,buf2d_w
		mov ebx,buf2d_h
		imul ebx,ecx
		mov ecx,ebx ;ecx = size  8 b
		shl ebx,2   ;ebx = size 32 b
		invoke mem.realloc,buf2d_data,ebx ;㢥«¨ç¨¢ ¥¬ ¯ ¬ïâì § ­¨¬ ¥¬ãî ¡ãä¥à®¬
		mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
		mov buf2d_bits,32
		mov edx,ebx ;edx = size 32 b
		sub ebx,ecx ;ebx = size 24 b
		mov eax,ecx
		;eax - à §¬¥à  8 ¡¨â­ëå ¤ ­­ëå
		;ebx - à §¬¥à 24 ¡¨â­ëå ¤ ­­ëå
		;edx - à §¬¥à 32 ¡¨â­ëå ¤ ­­ëå
		add ebx,buf2d_data
		add edx,buf2d_data
		mov edi,dword[buf_str8]
		cmp buf2d_bits,8
		jne .error2
		add eax,buf2d_data
		mov edi,edx
		;eax - 㪠§ â¥«ì ­  ª®­¥æ  8 ¡¨â­ëå ¤ ­­ëå
		;ebx - 㪠§ â¥«ì ­  ª®­¥æ 24 ¡¨â­ëå ¤ ­­ëå
		;edi - 㪠§ â¥«ì ­  ª®­¥æ 32 ¡¨â­ëå ¤ ­­ëå
		@@:
			sub edi,4 ;®â­¨¬ ¥¬ ¢ ­ ç «¥ 横« ,
			sub ebx,3 ; ¯®â®¬ã, ç⮠㪠§ â¥«¨ áâ®ïâ
			dec eax   ; §  ¯à¥¤¥« ¬¨ ¡ãä¥à®¢
			mov edx,dword[ebx]
			mov dword[edi],edx
			mov dl,byte[eax]
			mov byte[edi+3],dl
			loop @b

		jmp .end_conv
	.error1:
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n24b
		jmp .end_conv
	.error2:
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n8b
	.end_conv:
	popad
	ret
endp

;äã­ªæ¨ï ª®¯¨àã¥â ¨§®¡à ¦¥­¨¥ ¨§ ¡ãä¥à  buf_source (24b|32b) ¢ buf_destination (24b)
; 㪠§ë¢ îâáï ª®®à¤¨­ âë ¢áâ ¢ª¨ ¡ãä¥à  buf_source ®â­®á¨â¥«ì­® buf_destination
; ¯à®§à ç­®áâì ¯à¨ ª®¯¨à®¢ ­¨¨ ­¥ ãç¨â뢠¥âáï
align 4
proc buf_bit_blt, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
	locals
		right_bytes dd ?
	endl
	pushad

	mov edi,[buf_source]
	cmp buf2d_bits,24
	je .sou24
	cmp buf2d_bits,32
	je .sou32
		jmp .copy_end ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï

	.sou24: ;¢ ¨áâ®ç­¨ª¥ 24 ¡¨â­ ï ª à⨭ª 
	mov eax,buf2d_w
	mov edx,buf2d_h ;¢ëá®â  ª®¯¨à㥬®© ª à⨭ª¨
	mov esi,buf2d_data ;¤ ­­ë¥ ª®¯¨à㥬®© ª à⨭ª¨

	mov edi,[buf_destination]
	cmp buf2d_bits,24
	jne .copy_end ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
	mov ebx,[coord_x] ;¢ ebx ¢à¥¬¥­­® áâ ¢¨¬ ®âáâ㯠¨§®¡à ¦¥­¨ï (¤«ï ¯à®¢¥àª¨)
	cmp ebx,buf2d_w   ;¯à®¢¥à塞 ¢« §¨â «¨ ¨§®¡à ¦¥­¨¥ ¯® è¨à¨­¥
	jge .copy_end     ;¥á«¨ ¨§®¡à ¦¥­¨¥ ¯®«­®áâìî ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã
		mov ebx,buf2d_h ;ebx - ¢ëá®â  ®á­®¢­®£® ¡ãä¥à 
		mov ecx,[coord_y]
		cmp ecx,ebx
		jge .copy_end ;¥á«¨ ª®®à¤¨­ â  'y' ¡®«ìè¥ ¢ëá®âë ¡ãä¥à 
		add ecx,edx ;ecx - ­¨¦­ïï ª®®à¤¨­ â  ª®¯¨à㥬®© ª à⨭ª¨
		cmp ecx,ebx
		jle @f
			sub ecx,ebx
			sub edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨, ¢ á«ãç¥ ª®£¤  ®­  ¢ë« §¨â §  ­¨¦­îî £à ­¨æã
		@@:
		mov ebx,buf2d_w
		mov ecx,ebx ;ecx ¨á¯®«ì§ã¥¬ ¤«ï ¢à¥¬¥­­ëå 楫¥©
		imul ecx,[coord_y]
		add ecx,[coord_x]
		lea ecx,[ecx+ecx*2]
		add ecx,buf2d_data
		sub ebx,eax
		mov edi,ecx ;edi 㪠§ â¥«ì ­  ¤ ­­ë¥ ¡ãä¥à , ªã¤  ¡ã¤¥â ¯à®¨§¢®¤¨âáï ª®¯¨à®¢ ­¨¥

	mov [right_bytes],0
	mov ecx,[coord_x]
	cmp ecx,ebx
	jl @f
		sub ecx,ebx
		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
		lea ecx,[ecx+ecx*2] ;ecx - ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª à⨭ª¨, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî áâ®à®­ã
		mov [right_bytes],ecx
	@@:

	lea eax,[eax+eax*2] ;ª®««¨ç¥á⢮ ¡ ©â ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨
	lea ebx,[ebx+ebx*2] ;ª®««¨ç¥á⢮ ¡ ©â ¢ 1-© áâப¥ ¡ãä¥à  ¬¨­ãá ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨

	cld
	cmp [right_bytes],0
	jg .copy_1
	.copy_0: ;¯à®á⮥ ª®¯¨à®¢ ­¨¥
		mov ecx,eax
		rep movsb
		add edi,ebx
		dec edx
		cmp edx,0
		jg .copy_0
	jmp .copy_end
	.copy_1: ;­¥ ¯à®á⮥ ª®¯¨à®¢ ­¨¥ (ª à⨭ª  ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã)
		mov ecx,eax
		rep movsb
		add edi,ebx
		add esi,[right_bytes] ;¤®¡ ¢«ï¥¬ ¡ ©âë, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî £à ­¨æã
		dec edx
		cmp edx,0
		jg .copy_1
	jmp .copy_end

	.sou32: ;¢ ¨áâ®ç­¨ª¥ 32 ¡¨â­ ï ª à⨭ª 
	mov eax,buf2d_w
	mov edx,buf2d_h ;¢ëá®â  ª®¯¨à㥬®© ª à⨭ª¨
	mov esi,buf2d_data ;¤ ­­ë¥ ª®¯¨à㥬®© ª à⨭ª¨

	mov edi,[buf_destination]
	cmp buf2d_bits,24
	jne .copy_end ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
	mov ebx,[coord_x] ;¢ ebx ¢à¥¬¥­­® áâ ¢¨¬ ®âáâ㯠¨§®¡à ¦¥­¨ï (¤«ï ¯à®¢¥àª¨)
	cmp ebx,buf2d_w   ;¯à®¢¥à塞 ¢« §¨â «¨ ¨§®¡à ¦¥­¨¥ ¯® è¨à¨­¥
	jge .copy_end     ;¥á«¨ ¨§®¡à ¦¥­¨¥ ¯®«­®áâìî ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã
		mov ebx,buf2d_h ;ebx - ¢ëá®â  ®á­®¢­®£® ¡ãä¥à 
		mov ecx,[coord_y]
		cmp ecx,ebx
		jge .copy_end ;¥á«¨ ª®®à¤¨­ â  'y' ¡®«ìè¥ ¢ëá®âë ¡ãä¥à 
		add ecx,edx ;ecx - ­¨¦­ïï ª®®à¤¨­ â  ª®¯¨à㥬®© ª à⨭ª¨
		cmp ecx,ebx
		jle @f
			sub ecx,ebx
			sub edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨, ¢ á«ãç¥ ª®£¤  ®­  ¢ë« §¨â §  ­¨¦­îî £à ­¨æã
		@@:
		mov ebx,buf2d_w
		mov ecx,ebx ;ecx ¨á¯®«ì§ã¥¬ ¤«ï ¢à¥¬¥­­ëå 楫¥©
		imul ecx,[coord_y]
		add ecx,[coord_x]
		lea ecx,[ecx+ecx*2]
		add ecx,buf2d_data
		sub ebx,eax
		mov edi,ecx ;edi 㪠§ â¥«ì ­  ¤ ­­ë¥ ¡ãä¥à , ªã¤  ¡ã¤¥â ¯à®¨§¢®¤¨âáï ª®¯¨à®¢ ­¨¥

	mov [right_bytes],0
	mov ecx,[coord_x]
	cmp ecx,ebx
	jl @f
		sub ecx,ebx
		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
		shl ecx,2 ;ecx - ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª à⨭ª¨, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî áâ®à®­ã
		mov [right_bytes],ecx
	@@:

	;eax - ª®««¨ç¥á⢮ ¯¨ªá¥«¥© ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨
	lea ebx,[ebx+ebx*2] ;ª®««¨ç¥á⢮ ¡ ©â ¢ 1-© áâப¥ ¡ãä¥à  ¬¨­ãá ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨

	cld
	cmp [right_bytes],0
	jg .copy_3
	.copy_2: ;¯à®á⮥ ª®¯¨à®¢ ­¨¥
		mov ecx,eax
		@@:
			movsw
			movsb
			inc esi
			loop @b
		add edi,ebx
		dec edx
		cmp edx,0
		jg .copy_2
	jmp .copy_end
	.copy_3: ;­¥ ¯à®á⮥ ª®¯¨à®¢ ­¨¥ (ª à⨭ª  ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã)
		mov ecx,eax
		@@:
			movsw
			movsb
			inc esi
			loop @b
		add edi,ebx
		add esi,[right_bytes] ;¤®¡ ¢«ï¥¬ ¡ ©âë, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî £à ­¨æã
		dec edx
		cmp edx,0
		jg .copy_3

	.copy_end:
	popad
	ret
endp

;input:
; esi = pointer to color1 + transparent
; edi = pointer to background color2
;output:
; [edi] = combine color
align 4
combine_colors:
	push ax bx cx dx
	mov bx,0x00ff ;---get transparent---
	mov cl,byte[esi+3] ;pro
	xor ch,ch
	sub bx,cx ;256-pro
	;---blye---
	xor ah,ah
	mov al,byte[esi]
	imul ax,bx
	xor dh,dh
	mov dl,byte[edi]
	imul dx,cx
	add ax,dx
	mov byte[edi],ah
	;---green---
	xor ah,ah
	mov al,byte[esi+1]
	imul ax,bx
	xor dh,dh
	mov dl,byte[edi+1]
	imul dx,cx
	add ax,dx
	mov byte[edi+1],ah
	;---red---
	xor ah,ah
	mov al,byte[esi+2]
	imul ax,bx
	xor dh,dh
	mov dl,byte[edi+2]
	imul dx,cx
	add ax,dx
	mov byte[edi+2],ah

	pop dx cx bx ax
	ret

;äã­ªæ¨ï ª®¯¨àã¥â ¨§®¡à ¦¥­¨¥ ¨§ ¡ãä¥à  buf_source (32b) ¢ buf_destination (24b)
; 㪠§ë¢ îâáï ª®®à¤¨­ âë ¢áâ ¢ª¨ ¡ãä¥à  buf_source ®â­®á¨â¥«ì­® buf_destination
; ¯à¨ ª®¯¨à®¢ ­¨¨ ãç¨â뢠¥âáï ¯à®§à ç­®áâì
align 4
proc buf_bit_blt_transp, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
	locals
		right_bytes dd ?
	endl
	pushad

	mov edi,[buf_source]
	cmp buf2d_bits,32
	jne .copy_end ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
	mov eax,buf2d_w
	mov edx,buf2d_h ;¢ëá®â  ª®¯¨à㥬®© ª à⨭ª¨
	mov esi,buf2d_data ;¤ ­­ë¥ ª®¯¨à㥬®© ª à⨭ª¨

	mov edi,[buf_destination]
	cmp buf2d_bits,24
	jne .copy_end ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
		mov ebx,buf2d_h ;ebx - ¢ëá®â  ®á­®¢­®£® ¡ãä¥à 
		mov ecx,[coord_y]
		cmp ecx,ebx
		jge .copy_end ;¥á«¨ ª®®à¤¨­ â  'y' ¡®«ìè¥ ¢ëá®âë ¡ãä¥à 
		add ecx,edx ;ecx - ­¨¦­ïï ª®®à¤¨­ â  ª®¯¨à㥬®© ª à⨭ª¨
		cmp ecx,ebx
		jle @f
			sub ecx,ebx
			sub edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨, ¢ á«ãç¥ ª®£¤  ®­  ¢ë« §¨â §  ­¨¦­îî £à ­¨æã
		@@:
		mov ebx,buf2d_w
		mov ecx,ebx ;ecx ¨á¯®«ì§ã¥¬ ¤«ï ¢à¥¬¥­­ëå 楫¥©
		imul ecx,[coord_y]
		add ecx,[coord_x]
		lea ecx,[ecx+ecx*2]
		add ecx,buf2d_data
		sub ebx,eax
		mov edi,ecx ;edi 㪠§ â¥«ì ­  ¤ ­­ë¥ ¡ãä¥à , ªã¤  ¡ã¤¥â ¯à®¨§¢®¤¨âáï ª®¯¨à®¢ ­¨¥

	mov [right_bytes],0
	mov ecx,[coord_x]
	cmp ecx,ebx
	jl @f
		sub ecx,ebx
		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
		shl ecx,2 ;ecx - ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª à⨭ª¨, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî áâ®à®­ã
		mov [right_bytes],ecx
	@@:

	lea ebx,[ebx+ebx*2] ;ª®««¨ç¥á⢮ ¡ ©â ¢ 1-© áâப¥ ¡ãä¥à  ¬¨­ãá ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨

	cld
	cmp [right_bytes],0
	jg .copy_1
	.copy_0: ;¯à®á⮥ ª®¯¨à®¢ ­¨¥
		mov ecx,eax
		@@:
			call combine_colors
			add edi,3
			add esi,4
			loop @b
		add edi,ebx
		dec edx
		cmp edx,0
		jg .copy_0
	jmp .copy_end
	.copy_1: ;­¥ ¯à®á⮥ ª®¯¨à®¢ ­¨¥ (ª à⨭ª  ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã)
		mov ecx,eax
		@@:
			call combine_colors
			add edi,3
			add esi,4
			loop @b
		add edi,ebx
		add esi,[right_bytes] ;¤®¡ ¢«ï¥¬ ¡ ©âë, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî £à ­¨æã
		dec edx
		cmp edx,0
		jg .copy_1

	.copy_end:
	popad
	ret
endp

;input:
; ebx - color1
; esi = pointer to transparent
; edi = pointer to background color2
;output:
; [edi] = combine color
align 4
combine_colors_2:
	push ax ebx cx dx si
	mov cl,byte[esi] ;pro
	xor ch,ch
	mov si,0x00ff ;---get transparent---
	sub si,cx ;256-pro

		;---blye---
		mov al,bl
		xor ah,ah
		shr ebx,8
		imul ax,si
		xor dh,dh
		mov dl,byte[edi]
		imul dx,cx
		add ax,dx
		mov byte[edi],ah
		;---green---
		mov al,bl
		xor ah,ah
		shr ebx,8
		imul ax,si
		xor dh,dh
		mov dl,byte[edi+1]
		imul dx,cx
		add ax,dx
		mov byte[edi+1],ah
		;---red---
		mov al,bl
		xor ah,ah
		imul ax,si
		xor dh,dh
		mov dl,byte[edi+2]
		imul dx,cx
		add ax,dx
		mov byte[edi+2],ah

	pop si dx cx ebx ax
	ret

;äã­ªæ¨ï ª®¯¨àã¥â ¨§®¡à ¦¥­¨¥ ¨§ ¡ãä¥à  buf_source (8b) ¢ buf_destination (24b)
; 㪠§ë¢ îâáï ª®®à¤¨­ âë ¢áâ ¢ª¨ ¡ãä¥à  buf_source ®â­®á¨â¥«ì­® buf_destination
align 4
proc buf_bit_blt_alpha, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword, color:dword
	locals
		right_bytes dd ?
		dest_w_bytes dd ? ;ª®««¨ç¥á⢮ ¡ ©â ¢ ¡ãä¥à¥ ¯à¨¥¬­¨ª¥ ¯® è¨à¨­¥ - è¨à¨­  ¢áâ ¢«ï¥¬®© ª à⨭ª¨
	endl
	pushad

	mov edi,[buf_source]
	cmp buf2d_bits,8
	jne .error1 ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
	mov eax,buf2d_w
	mov edx,buf2d_h ;¢ëá®â  ª®¯¨à㥬®© ª à⨭ª¨
	mov esi,buf2d_data ;¤ ­­ë¥ ª®¯¨à㥬®© ª à⨭ª¨

	mov edi,[buf_destination]
	cmp buf2d_bits,24
	jne .error2 ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
	mov ebx,[coord_x] ;¢ ebx ¢à¥¬¥­­® áâ ¢¨¬ ®âáâ㯠¨§®¡à ¦¥­¨ï (¤«ï ¯à®¢¥àª¨)
	cmp ebx,buf2d_w   ;¯à®¢¥à塞 ¢« §¨â «¨ ¨§®¡à ¦¥­¨¥ ¯® è¨à¨­¥
	jge .copy_end     ;¥á«¨ ¨§®¡à ¦¥­¨¥ ¯®«­®áâìî ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã
		mov ebx,buf2d_h ;ebx - ¢ëá®â  ®á­®¢­®£® ¡ãä¥à 
		mov ecx,[coord_y]
		cmp ecx,ebx
		jge .copy_end ;¥á«¨ ª®®à¤¨­ â  'y' ¡®«ìè¥ ¢ëá®âë ¡ãä¥à 
		add ecx,edx ;ecx - ­¨¦­ïï ª®®à¤¨­ â  ª®¯¨à㥬®© ª à⨭ª¨
		cmp ecx,ebx
		jle @f
			sub ecx,ebx
			sub edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨, ¢ á«ãç¥ ª®£¤  ®­  ¢ë« §¨â §  ­¨¦­îî £à ­¨æã
		@@:
		mov ebx,buf2d_w
		mov ecx,ebx ;ecx ¨á¯®«ì§ã¥¬ ¤«ï ¢à¥¬¥­­ëå 楫¥©
		imul ecx,[coord_y]
		add ecx,[coord_x]
		lea ecx,[ecx+ecx*2]
		add ecx,buf2d_data
		sub ebx,eax
		mov edi,ecx ;edi 㪠§ â¥«ì ­  ¤ ­­ë¥ ¡ãä¥à , ªã¤  ¡ã¤¥â ¯à®¨§¢®¤¨âáï ª®¯¨à®¢ ­¨¥

	mov [right_bytes],0
	mov ecx,[coord_x]
	cmp ecx,ebx
	jl @f
		sub ecx,ebx
		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
		;ecx - ç¨á«® ¯¨ªá¥«¥© ¢ 1-© áâப¥ ª à⨭ª¨, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî áâ®à®­ã
		mov [right_bytes],ecx
	@@:

	lea ebx,[ebx+ebx*2] ;ª®««¨ç¥á⢮ ¡ ©â ¢ 1-© áâப¥ ¡ãä¥à  ¬¨­ãá ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨
	mov [dest_w_bytes],ebx
	mov ebx,[color]

	cld
	cmp [right_bytes],0
	jg .copy_1
	.copy_0: ;¯à®á⮥ ª®¯¨à®¢ ­¨¥
		mov ecx,eax
		@@:
			call combine_colors_2
			add edi,3
			inc esi
			loop @b
		add edi,[dest_w_bytes]
		dec edx
		cmp edx,0
		jg .copy_0
	jmp .copy_end
	.copy_1: ;­¥ ¯à®á⮥ ª®¯¨à®¢ ­¨¥ (ª à⨭ª  ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã)
		mov ecx,eax
		@@:
			call combine_colors_2
			add edi,3
			inc esi
			loop @b
		add edi,[dest_w_bytes]
		add esi,[right_bytes] ;¤®¡ ¢«ï¥¬ ¡ ©âë, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî £à ­¨æã
		dec edx
		cmp edx,0
		jg .copy_1

	jmp .copy_end
	.error1:
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n8b
		jmp .copy_end
	.error2:
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n24b
	.copy_end:
	popad
	ret
endp

;¯à¥®¡à §®¢ ­¨¥ 8-¡¨â­®£® ¡ãä¥à  à §¬¥à®¬ 16*16 ¢ à §¬¥à 1*256 ᨬ¢®«®¢
align 4
proc buf_convert_text_matrix, buf_struc:dword
	locals
		tmp_mem dd ?
		c1 dw ?
		c2 dd ?
		c3 dw ?
	endl
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,8
	jne .error
		mov ecx,buf2d_h
		mov ebx,ecx
		shr ebx,4 ;¯à¥¤¯®« £ ¥¬ çâ® ¢ ¡ãä¥à¥ 16 áâப á ᨬ¢®« ¬¨, ¯®â®¬ã ¤¥«¨¬ ­  2^4
		mov edx,buf2d_w
		imul ecx,edx ;ecx = size  8 b
		invoke mem.alloc,ecx ;¢ë¤¥«ï¥¬ ¢à¥¬¥­­ãî ¯ ¬ïâì
		mov [tmp_mem],eax ;eax - new memory

		shr edx,4 ;¯à¥¤¯®« £ ¥¬ çâ® ¢ ¡ãä¥à¥ 16 ª®«®­®ª á ᨬ¢®« ¬¨, ¯®â®¬ã ¤¥«¨¬ ­  2^4
		mov eax,ebx
		imul ebx,edx ;¢ëç¨á«ï¥¬ ª®®«¨ç¥á⢮ ¯¨ªá¥«¥© ­  1 ᨬ¢®«
		;eax = bhe - ¢ëá®â  ¡ãª¢ë
		;ebx = bwi*bhe - ª®««¨ç¥á⢮ ¯¨ªá¥«¥© ¢ 1-© ¡ãª¢¥
		;edx = bwi - è¨à¨­  ¡ãª¢ë
		;ecx,esi,edi - ¨á¯®«ì§ãîâáï ¢ 横«¥ .c_0
		shr buf2d_w,4
		shl buf2d_h,4 ;¯à¥®¡à §®¢ë¢ ¥¬ à §¬¥àë ¡ãä¥à 

		cld
		mov esi,buf2d_data
		mov edi,[tmp_mem]
		mov word[c3],16
		.c_3:
			mov dword[c2],eax
			.c_2:
				mov word[c1],16
				.c_1:
					mov ecx,edx ;.c_0:
					rep movsb
					add edi,ebx
					sub edi,edx ;edi+=(bwi*bhe-bwi)
					dec word[c1]
					cmp word[c1],0
					jg .c_1
				add edi,edx
				shl ebx,4
				sub edi,ebx ;edi-=(16*bwi*bhe-bwi)
				shr ebx,4
				dec dword[c2]
				cmp dword[c2],0
				jg .c_2
			sub edi,ebx
			shl ebx,4
			add edi,ebx ;edi+=(15*bwi*bhe)
			shr ebx,4
			dec word[c3]
			cmp word[c3],0
			jg .c_3

		mov edi,dword[buf_struc] ;ª®¯¨à®¢ ­¨¥ ­®¢®© ¬ âà¨æë ¢ ®á­®¢­®© ¡ãä¥à
		mov edi,buf2d_data
		mov esi,[tmp_mem]
		mov ecx,ebx
		shl ecx,8
		rep movsb
		invoke mem.free,[tmp_mem] ;ç¨á⨬ ¢à¥¬¥­­ãî ¯ ¬ïâì
		jmp .end_conv
	.error:
		stdcall print_err,sz_buf2d_convert_text_matrix,txt_err_n8b
	.end_conv:
	popad
	ret
endp

align 4
buf_s_matr buf_2d_header ? ;«®ª «ì­ ï ¬ âà¨æ  ᨬ¢®« 

align 4
proc buf_draw_text, buf_struc:dword, buf_t_matr:dword, text:dword, coord_x:dword, coord_y:dword, color:dword
	locals
		buf_t_matr_offs dd ?
	endl
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .error2
	mov edi,dword[buf_t_matr]
	cmp buf2d_bits,8
	jne .error1
		mov edx,buf2d_data
		mov [buf_t_matr_offs],edx
		mov ecx,BUF_STRUCT_SIZE ;ª®¯¨à㥬 áâàãªâãàã ⥪á⮢®© ¬ âà¨æë
		mov esi,edi
		lea edi,[buf_s_matr]
		cld
		rep movsb
		lea edi,[buf_s_matr]
		shr buf2d_h,8 ;¤¥«¨¬ ¢ëá®âã ᨬ¢®«ì­®£® ¡ãä¥à  ­  256, ¤«ï ­ å®¦¤¥­¨ï ¢ëá®âë 1-£® ᨬ¢®« 
		mov ebx,buf2d_h ;¡¥à¥¬ ¢ëá®âã ᨬ¢®« 
		mov ecx,buf2d_w ;¡¥à¥¬ è¨à¨­ã ᨬ¢®« 

		mov eax,[coord_x]
		mov esi,[text]
		cmp byte[esi],0
		je .end_draw ;¥á«¨ ¯ãáâ ï áâப 
		@@:
			xor edx,edx
			mov dl,byte[esi] ;¡¥à¥¬ ª®¤ ᨬ¢®« 
			imul edx,ebx ;㬭®¦ ¥¬ ¥£® ­  ¢ëá®âã ᨬ¢®« 
			imul edx,ecx ;㬭®¦ ¥¬ ­  è¨à¨­ã ᨬ¢®« 
			add edx,[buf_t_matr_offs] ;¯à¨¡ ¢«ï¥¬ ᬥ饭¨¥ 0-£® ᨬ¢®« , â. ¥. ¯®«ãç ¥âáï ᬥ饭¨¥ ¢ë¢®¤¨¬®£® ᨬ¢®« 
			mov buf2d_data,edx ;¢ «®ª «ì­ë© ¡ãä¥à ᨬ¢®« , áâ ¢¨¬ 㪠§ â¥«ì ­  ­ã¦­ë© ᨬ¢®« ¨§ ¡ãä¥à  buf_t_matr
			stdcall buf_bit_blt_alpha, [buf_struc], eax,[coord_y], edi,[color]
			add eax,ecx
			.new_s:
				inc esi
				cmp byte[esi],13
				jne .no_13
					mov eax,[coord_x]
					add [coord_y],ebx
					jmp .new_s
				.no_13:
			cmp byte[esi],0
			jne @b
		jmp .end_draw
	.error1:
		stdcall print_err,sz_buf2d_draw_text,txt_err_n8b
		jmp .end_draw
	.error2:
		stdcall print_err,sz_buf2d_draw_text,txt_err_n24b
	.end_draw:
	popad
	ret
endp

align 4
proc print_err, fun:dword, mes:dword ;¢ë¢®¤¨¬ á®®¡é¥­¨¥ ®¡ 訡ª¥ ­  ¤®áªã ®â« ¤ª¨
	pushad
	mov eax,63
	mov ebx,1

	mov esi,[fun]
	@@:
		mov cl,byte[esi]
		int 0x40
		inc esi
		cmp byte[esi],0
		jne @b
	mov cl,':'
	int 0x40
	mov cl,' '
	int 0x40
	mov esi,[mes]
	@@:
		mov cl,byte[esi]
		int 0x40
		inc esi
		cmp byte[esi],0
		jne @b
	popad
	ret
endp

;input:
; ebp+8  = p0
; ebp+12 = p1
align 4
line_len4i:
	push ebp
	mov ebp,esp
		finit
		fild word [ebp+8]
		fisub word [ebp+12]
		fmul st0,st0 ;st0=x^2
		fild word [ebp+10]
		fisub word [ebp+14]
		fmul st0,st0 ;st0=y^2
		fadd st0,st1
		fsqrt
		fstp dword [ebp+12]
	pop ebp
	ret 4 ;8

align 4
proc buf_cruve_bezier, buffer:dword, coord_p0:dword,coord_p1:dword,coord_p2:dword, color:dword
	locals
		delt_t dd ?
		opr_param dd ?
		v_poi_0 dd ?
	endl
	pushad

;float t, xt,yt;
;for(t=.0;t<1.;t+=.005){
;  xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
;  yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
;  dc.SetPixel(xt,yt,255L);
;}

	mov edx,[color] ;set cruve color
	mov edi,[buffer]
	xor ebx,ebx
	xor ecx,ecx

	finit

	; calculate delta t
	stdcall line_len4i, dword[coord_p1],dword[coord_p0]
	fadd dword[esp]
	add esp,4 ;pop ...

	stdcall line_len4i, dword[coord_p2],dword[coord_p1]
	fadd dword[esp]
	add esp,4 ;pop ...

	fadd st0,st0 ; len*=2
	ftst
	fstsw ax

	fld1
	sahf
	jle @f ;¨§¡¥£ ¥¬ ¤¥«¥­¨ï ­  0
		fdiv st0,st1
	@@:
	fstp dword[delt_t]

	finit

	;fild word[coord_p2+2] ;y2
	fild word[coord_p1+2] ;y1
	fild word[coord_p0+2] ;y0
	fild word[coord_p2] ;x2
	fild word[coord_p1] ;x1
	fild word[coord_p0] ;x0
	fld dword[delt_t]
	fldz ;t=.0

	@@:
		fld1
		fsub st0,st1 ;1.-t
		fmul st0,st0 ;pow(1.-t,2)
		fmul st0,st3 ;...*x0
		fstp dword[opr_param]

		fld1
		fsub st0,st1 ;1.-t
		fmul st0,st1 ;(1.-t)*t
		fadd st0,st0
		fmul st0,st4 ;...*x1
		mov esi,dword[opr_param]
		fstp dword[opr_param]

		fldz
		fadd st0,st1 ;0+t
		fmul st0,st0 ;t*t
		fmul st0,st5 ;...*x2

		fadd dword[opr_param]
		mov dword[opr_param],esi
		fadd dword[opr_param]
		fistp word[v_poi_0] ;x

		fld1
		fsub st0,st1 ;1.-t
		fmul st0,st0 ;pow(1.-t,2)
		fmul st0,st6 ;...*y0
		fstp dword[opr_param]

		fld1
		fsub st0,st1 ;1.-t
		fmul st0,st1 ;(1.-t)*t
		fadd st0,st0
		fmul st0,st7 ;...*y1
		mov esi,dword[opr_param]
		fstp dword[opr_param]

		fldz
		fadd st0,st1 ;0+t
		fmul st0,st0 ;t*t
		fimul word[coord_p2+2] ;...*y2

		fadd dword[opr_param]
		mov dword[opr_param],esi
		fadd dword[opr_param]
		fistp word[v_poi_0+2] ;y

		mov eax,1
		mov bx,word[v_poi_0+2]
		mov cx,word[v_poi_0]
		call draw_pixel

		fadd st0,st1 ;t+dt

		fld1
		fcomp
		fstsw ax
		sahf
	jae @b

	popad
	ret
endp

txt_err_n8b db 'need buffer 8 bit',13,10,0
txt_err_n24b db 'need buffer 24 bit',13,10,0

align 16
EXPORTS:
	dd sz_lib_init, lib_init
	dd sz_buf2d_create, buf_create
	dd sz_buf2d_create_f_img, buf_create_f_img
	dd sz_buf2d_clear, buf_clear
	dd sz_buf2d_draw, buf_draw_buf
	dd sz_buf2d_delete, buf_delete
	dd sz_buf2d_line, buf_line_brs
	dd sz_buf2d_rect_by_size, buf_rect_by_size
	dd sz_buf2d_filled_rect_by_size, buf_filled_rect_by_size
	dd sz_buf2d_circle, buf_circle
	dd sz_buf2d_img_hdiv2, buf_img_hdiv2
	dd sz_buf2d_img_wdiv2, buf_img_wdiv2
	dd sz_buf2d_conv_24_to_8, buf_conv_24_to_8
	dd sz_buf2d_conv_24_to_32, buf_conv_24_to_32
	dd sz_buf2d_bit_blt, buf_bit_blt
	dd sz_buf2d_bit_blt_transp, buf_bit_blt_transp
	dd sz_buf2d_bit_blt_alpha, buf_bit_blt_alpha
	dd sz_buf2d_cruve_bezier, buf_cruve_bezier
	dd sz_buf2d_convert_text_matrix, buf_convert_text_matrix
	dd sz_buf2d_draw_text, buf_draw_text
	dd sz_buf2d_crop_color, buf_crop_color
	dd sz_buf2d_offset_h, buf_offset_h
	dd 0,0
	sz_lib_init db 'lib_init',0
	sz_buf2d_create db 'buf2d_create',0
	sz_buf2d_create_f_img db 'buf2d_create_f_img',0
	sz_buf2d_clear db 'buf2d_clear',0 ;®ç¨á⪠ ¡ãä¥à  㪠§ ­­ë¬ 梥⮬
	sz_buf2d_draw db 'buf2d_draw',0
	sz_buf2d_delete db 'buf2d_delete',0
	sz_buf2d_line db 'buf2d_line',0 ;à¨á®¢ ­¨¥ «¨­¨¨
	sz_buf2d_rect_by_size db 'buf2d_rect_by_size',0 ;à¨á®¢ ­¨¥ à ¬ª¨ ¯àאַ㣮«ì­¨ª , 2-ï ª®®à¤¨­ â  § ¤ ­  ¯® à §¬¥àã
	sz_buf2d_filled_rect_by_size db 'buf2d_filled_rect_by_size',0 ;à¨á®¢ ­¨¥ § «¨â®£® ¯àאַ㣮«ì­¨ª , 2-ï ª®®à¤¨­ â  § ¤ ­  ¯® à §¬¥àã
	sz_buf2d_circle db 'buf2d_circle',0 ;à¨á®¢ ­¨¥ ®ªà㦭®áâ¨
	sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 ;ᦠ⨥ ¨§®¡à ¦¥­¨ï ¯® ¢ëá®â¥ ¢ 2 à §  (à §¬¥à ¡ãä¥à  ­¥ ¬¥­ï¥âáï)
	sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 ;ᦠ⨥ ¨§®¡à ¦¥­¨ï ¯® è¨à¨­¥ ¢ 2 à §  (à §¬¥à ¡ãä¥à  ­¥ ¬¥­ï¥âáï)
	sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0
	sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0 
	sz_buf2d_bit_blt db 'buf2d_bit_blt',0
	sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0
	sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0
	sz_buf2d_cruve_bezier db 'buf2d_cruve_bezier',0
	sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0
	sz_buf2d_draw_text db 'buf2d_draw_text',0
	sz_buf2d_crop_color db 'buf2d_crop_color',0
	sz_buf2d_offset_h db 'buf2d_offset_h',0