Subversion Repositories Kolibri OS

Rev

Rev 2975 | Rev 3105 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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] ;высота буфера
  18. buf2d_l equ word[edi+4]
  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. vox_offs_tree_table equ 4
  52. vox_offs_data equ 12
  53.  
  54. ;input:
  55. ; eax = указатель на функцию выделения памяти
  56. ; ebx = ... освобождения памяти
  57. ; ecx = ... перераспределения памяти
  58. ; edx = ... загрузки библиотеки (пока не используется)
  59. align 16
  60. lib_init:
  61.         mov dword[mem.alloc], eax
  62.         mov dword[mem.free], ebx
  63.         mov dword[mem.realloc], ecx
  64.         mov dword[dll.load], edx
  65.         ret
  66.  
  67. ;input:
  68. ; ebx = coord x
  69. ; ecx = coord y
  70. ; edx = pixel color
  71. ; edi = pointer to buffer struct
  72. align 4
  73. draw_pixel:
  74.         ;cmp buf2d_bits,24
  75.         ;jne @f
  76.         bt ebx,31
  77.         jc @f
  78.         bt ecx,31
  79.         jc @f
  80.         cmp ebx,buf2d_w
  81.         jge @f
  82.         cmp ecx,buf2d_h
  83.         jge @f
  84.         push esi
  85.                 mov esi,buf2d_w ;size x
  86.                 imul esi,ecx ;size_x*y
  87.                 add esi,ebx      ;size_x*y+x
  88.                 cmp buf2d_bits,8
  89.                 je .beg8
  90.                 cmp buf2d_bits,32
  91.                 je .beg32
  92.                         lea esi,[esi+esi*2] ;(size_x*y+x)*3
  93.                         add esi,buf2d_data  ;ptr+(size_x*y+x)*3
  94.                         mov word[esi],dx ;copy pixel color
  95.                         ror edx,16
  96.                         mov byte[esi+2],dl
  97.                         ror edx,16
  98.                         jmp .end_draw
  99.                 .beg8: ;рисование точки в 8 битном буфере
  100.                         add esi,buf2d_data  ;ptr+(size_x*y+x)
  101.                         mov byte[esi],dl
  102.                         jmp .end_draw
  103.                 .beg32: ;рисование точки в 32 битном буфере
  104.                         shl esi,2
  105.                         add esi,buf2d_data  ;ptr+(size_x*y+x)
  106.                         mov dword[esi],edx
  107.                 .end_draw:
  108.         pop esi
  109.         @@:
  110.         ret
  111.  
  112. ;input:
  113. ; ebx = coord x
  114. ; ecx = coord y
  115. ; edi = pointer to buffer struct
  116. ;output:
  117. ; eax = цвет точки
  118. ; в случае ошибки eax = 0xffffffff
  119. align 4
  120. get_pixel_8:
  121.         mov eax,0xffffffff
  122.  
  123.         bt ebx,31
  124.         jc @f
  125.         bt ecx,31
  126.         jc @f
  127.         cmp ebx,buf2d_w
  128.         jge @f
  129.         cmp ecx,buf2d_h
  130.         jge @f
  131.         push esi
  132.                 mov esi,buf2d_w ;size x
  133.                 imul esi,ecx ;size_x*y
  134.                 add esi,ebx      ;size_x*y+x
  135.                 add esi,buf2d_data  ;ptr+(size_x*y+x)
  136.  
  137.                 movzx eax,byte[esi] ;copy pixel color
  138.         pop esi
  139.         @@:
  140.         ret
  141.  
  142. ;input:
  143. ; ebx = coord x
  144. ; ecx = coord y
  145. ; edi = pointer to buffer struct
  146. ;output:
  147. ; eax = цвет точки
  148. ; в случае ошибки eax = 0xffffffff
  149. align 4
  150. get_pixel_24:
  151.         mov eax,0xffffffff
  152.  
  153.         bt ebx,31
  154.         jc @f
  155.         bt ecx,31
  156.         jc @f
  157.         cmp ebx,buf2d_w
  158.         jge @f
  159.         cmp ecx,buf2d_h
  160.         jge @f
  161.         push esi
  162.                 mov esi,buf2d_w ;size x
  163.                 imul esi,ecx ;size_x*y
  164.                 add esi,ebx      ;size_x*y+x
  165.                 lea esi,[esi+esi*2] ;(size_x*y+x)*3
  166.                 add esi,buf2d_data  ;ptr+(size_x*y+x)*3
  167.  
  168.                 xor eax,eax
  169.                 mov ax,word[esi] ;copy pixel color
  170.                 ror eax,16
  171.                 mov al,byte[esi+2]
  172.                 ror eax,16
  173.         pop esi
  174.         @@:
  175.         ret
  176.  
  177. ;input:
  178. ; ebx = coord x
  179. ; ecx = coord y
  180. ; edi = pointer to buffer struct
  181. ;output:
  182. ; eax = цвет точки
  183. ; в случае ошибки eax = 0xffffffff
  184. align 4
  185. get_pixel_32:
  186.         mov eax,0xffffffff
  187.  
  188.         bt ebx,31
  189.         jc @f
  190.         bt ecx,31
  191.         jc @f
  192.         cmp ebx,buf2d_w
  193.         jge @f
  194.         cmp ecx,buf2d_h
  195.         jge @f
  196.         push esi
  197.                 mov esi,buf2d_w ;size x
  198.                 imul esi,ecx ;size_x*y
  199.                 add esi,ebx      ;size_x*y+x
  200.                 shl esi,2
  201.                 add esi,buf2d_data  ;ptr+(size_x*y+x)*4
  202.  
  203.                 mov eax,dword[esi] ;copy pixel color
  204.         pop esi
  205.         @@:
  206.         ret
  207.  
  208. ;input:
  209. ; ebx = coord x
  210. ; ecx = coord y
  211. ; edx = pixel color + transparent
  212. ; edi = pointer to buffer struct
  213. ; t_prop, m_prop - коэфициенты необходимые для вычисления степени прозрачности
  214. align 4
  215. transp_32 dd 0 ;цвет рисуемой точки + прозрачность
  216. align 4
  217. proc draw_pixel_transp, t_prop:dword, m_prop:dword
  218.         ;cmp buf2d_bits,24
  219.         ;jne @f
  220.         bt ebx,31
  221.         jc @f
  222.         bt ecx,31
  223.         jc @f
  224.         cmp ebx,buf2d_w
  225.         jge @f
  226.         cmp ecx,buf2d_h
  227.         jge @f
  228.         push eax ebx edx edi esi
  229.                 mov esi,buf2d_w ;size x
  230.                 imul esi,ecx ;size_x*y
  231.                 add esi,ebx      ;size_x*y+x
  232.                 lea esi,[esi+esi*2] ;(size_x*y+x)*3
  233.                 add esi,buf2d_data  ;ptr+(size_x*y+x)*3
  234.  
  235.                 mov edi,esi ;указатель на цвет фона
  236.                 mov dword[transp_32],edx ;цвет рисуемой точки
  237.  
  238.                 xor edx,edx
  239.                 mov eax,[t_prop]
  240.                 shl eax,8 ;*=256
  241.                 mov ebx,[m_prop]
  242.                 div ebx ;вычисляем коэф. прозрачности (должен быть от 0 до 255)
  243.                 bt ax,8
  244.                 jnc .over_255
  245.                         ;если коеф. прозрачности >=256 то уменьшаем его до 255
  246.                         mov al,0xff
  247.                 .over_255:
  248.  
  249.                 mov byte[transp_32+3],al ;прозрачность рисуемой точки
  250.                 mov esi,dword transp_32 ;указатель на цвет рисуемой точки
  251.  
  252.                 call combine_colors_0
  253.         pop esi edi edx ebx eax
  254.         @@:
  255.         ret
  256. endp
  257.  
  258. ;создание буфера
  259. align 4
  260. proc buf_create, buf_struc:dword
  261.         pushad
  262.         mov edi,dword[buf_struc]
  263.         mov ecx,buf2d_w
  264.         mov ebx,buf2d_h
  265.         imul ecx,ebx
  266.         cmp buf2d_bits,24
  267.         jne @f
  268.                 lea ecx,[ecx+ecx*2] ; 24 bit = 3
  269.                 ;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
  270.         @@:
  271.         cmp buf2d_bits,32
  272.         jne @f
  273.                 shl ecx,2 ; 32 bit = 4
  274.         @@:
  275.         invoke mem.alloc,ecx
  276.         mov buf2d_data,eax
  277.  
  278.         stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
  279.         popad
  280.         ret
  281. endp
  282.  
  283. ;создание буфера на основе изображения rgb
  284. align 4
  285. proc buf_create_f_img, buf_struc:dword, rgb_data:dword
  286.         pushad
  287.         mov edi,dword[buf_struc]
  288.         mov ecx,buf2d_w
  289.         mov ebx,buf2d_h
  290.         imul ecx,ebx
  291.         cmp buf2d_bits,24
  292.         jne @f
  293.                 lea ecx,[ecx+ecx*2] ; 24 bit = 3
  294.                 ;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
  295.         @@:
  296.         cmp buf2d_bits,32
  297.         jne @f
  298.                 shl ecx,2 ; 32 bit = 4
  299.         @@:
  300.         invoke mem.alloc,ecx
  301.         mov buf2d_data,eax
  302.  
  303.         cmp buf2d_bits,24
  304.         jne @f
  305.                 cld
  306.                 mov esi,[rgb_data]
  307.                 mov edi,eax ;eax=buf2d_data
  308.                 rep movsb ;копируем биты изображения в буфер
  309.                 jmp .end_create
  310.         @@:
  311.                 stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
  312.         .end_create:
  313.         popad
  314.         ret
  315. endp
  316.  
  317. align 4
  318. proc buf_clear, buf_struc:dword, color:dword ;очистка буфера заданым цветом
  319.         pushad
  320.         mov edi,dword[buf_struc]
  321.  
  322.         mov ecx,buf2d_w
  323.         mov ebx,buf2d_h
  324.         imul ecx,ebx
  325.  
  326.         cld
  327.  
  328.         cmp buf2d_bits,8
  329.         jne .end_clear_8
  330.                 mov edi,buf2d_data
  331.                 mov al,byte[color]
  332.                 rep stosb
  333.                 jmp .end_clear_32
  334.         .end_clear_8:
  335.  
  336.         cmp buf2d_bits,24
  337.         jne .end_clear_24
  338.                 mov edi,buf2d_data
  339.                 mov eax,dword[color]
  340.                 mov ebx,eax
  341.                 shr ebx,16
  342.                 @@:
  343.                         stosw
  344.                         mov byte[edi],bl
  345.                         inc edi
  346.                         loop @b
  347.                 jmp .end_clear_32
  348.         .end_clear_24:
  349.  
  350.         cmp buf2d_bits,32
  351.         jne .end_clear_32
  352.                 mov edi,buf2d_data
  353.                 mov eax,dword[color]
  354.                 rep stosd
  355.                 ;jmp .end_clear_32
  356.         .end_clear_32:
  357.         popad
  358.         ret
  359. endp
  360.  
  361. ;функция для обрезания буферов 8 и 24 битных, по заданому цвету.
  362. ;параметр opt задается комбинацией констант:
  363. ; BUF2D_OPT_CROP_TOP - обрезка сверху
  364. ; BUF2D_OPT_CROP_LEFT - обрезка слева
  365. ; BUF2D_OPT_CROP_BOTTOM - обрезка снизу
  366. ; BUF2D_OPT_CROP_RIGHT - обрезка справа
  367. align 4
  368. proc buf_crop_color, buf_struc:dword, color:dword, opt:dword
  369. locals
  370.         crop_r dd ?
  371. endl
  372.         pushad
  373.         mov edi,dword[buf_struc]
  374.         cmp buf2d_bits,24
  375.         jne .24end_f
  376.  
  377.         bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
  378.         jae .24no_crop_bottom
  379.                 mov eax,dword[color]
  380.                 mov edx,eax ;ax = colors - r,g
  381.                 shr edx,16 ;dl = color - b
  382.                 mov ecx,buf2d_h
  383.                 cmp ecx,1
  384.                 jle .24no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
  385.                 mov ebx,buf2d_w
  386.                 imul ecx,ebx
  387.                 lea esi,[ecx+ecx*2] ;esi=3*ecx
  388.                 add esi,buf2d_data
  389.                 cld
  390.                 @@:
  391.                         sub esi,3
  392.                         cmp word[esi],ax
  393.                         jne @f
  394.                         cmp byte[esi+2],dl
  395.                         jne @f
  396.                         loop @b
  397.                 @@:
  398.                 lea ebx,[ebx+ebx*2]
  399.                 xor edx,edx
  400.                 mov eax,buf2d_h
  401.                 imul eax,ebx
  402.                 add eax,buf2d_data ;eax - указатель на конец буфера изображения
  403.                 @@:
  404.                         add esi,ebx
  405.                         cmp esi,eax
  406.                         jge @f
  407.                         inc edx ;вычисляем число полных строк для обрезания
  408.                         loop @b
  409.                 @@:
  410.                 cmp edx,0
  411.                 je .24no_crop_bottom
  412.                         cmp edx,buf2d_h
  413.                         jge .24no_crop_bottom ;что-бы не получить пустой буфер
  414.                         sub buf2d_h,edx ;уменьшаем высоту буфера
  415.                         mov ecx,buf2d_h
  416.                         imul ecx,ebx ;ecx = новый размер изображения
  417.                         invoke mem.realloc,buf2d_data,ecx
  418.                         mov buf2d_data,eax ;на случай если изменился указатель на данные
  419.         .24no_crop_bottom:
  420.  
  421.         bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
  422.         jae .24no_crop_top
  423.                 mov eax,dword[color]
  424.                 mov edx,eax ;ax = colors - r,g
  425.                 shr edx,16 ;dl = color - b
  426.                 mov esi,buf2d_data
  427.                 mov ecx,buf2d_h
  428.                 cmp ecx,1
  429.                 jle .24no_crop_top ;проверяем на случай если высота буфера 1 пиксель
  430.                 dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
  431.                 mov ebx,buf2d_w
  432.                 imul ecx,ebx
  433.                 cld
  434.                 @@:
  435.                         cmp word[esi],ax
  436.                         jne @f
  437.                         cmp byte[esi+2],dl
  438.                         jne @f
  439.                         add esi,3
  440.                         loop @b
  441.                 @@:
  442.                 lea ebx,[ebx+ebx*2]
  443.                 xor edx,edx
  444.                 @@:
  445.                         sub esi,ebx
  446.                         cmp esi,buf2d_data
  447.                         jl @f
  448.                         inc edx ;вычисляем число полных строк для обрезания
  449.                         loop @b
  450.                 @@:
  451.                 cmp edx,0
  452.                 je .24no_crop_top
  453.                         xor eax,eax
  454.                         sub eax,edx
  455.                         mov ebx,buf2d_h
  456.                         sub ebx,edx
  457.                         stdcall buf_offset_h, edi, eax, edx, ebx ;сдвигаем изображение в буфере вверх (eax<0)
  458.                         sub buf2d_h,edx ;уменьшаем высоту буфера
  459.                         mov ecx,buf2d_h
  460.                         add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
  461.                         mov ebx,buf2d_w
  462.                         imul ecx,ebx
  463.                         lea ecx,[ecx+ecx*2]
  464.                         invoke mem.realloc,buf2d_data,ecx
  465.                         mov buf2d_data,eax ;на случай если изменился указатель на данные
  466.         .24no_crop_top:
  467.  
  468.         bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
  469.         jae .24no_crop_right
  470.                 mov eax,dword[color]
  471.                 mov edx,eax ;ax = colors - r,g
  472.                 shr edx,16 ;dl = color - b
  473.                 mov ebx,buf2d_w
  474.                 cmp ebx,1
  475.                 jle .24no_crop_right ;на случай если ширина буфера 1 пиксель
  476.                 lea ebx,[ebx+ebx*2]
  477.                 mov esi,ebx
  478.                 imul esi,buf2d_h
  479.                 add esi,buf2d_data ;esi - указатель на конец буфера изображения
  480.                 mov dword[crop_r],0
  481.                 cld
  482.                 .24found_beg_right:
  483.                 sub esi,3 ;двигаемся на 1-ну колонку влево
  484.                 mov ecx,buf2d_h ;восстановление ecx для нового цикла
  485.                 @@:
  486.                         cmp word[esi],ax
  487.                         jne .24found_right
  488.                         cmp byte[esi+2],dl
  489.                         jne .24found_right
  490.                         sub esi,ebx ;прыгаем на верхнюю строку
  491.                         loop @b
  492.                 inc dword[crop_r]
  493.  
  494.                 mov ecx,buf2d_w
  495.                 dec ecx ;1 колонка на запас
  496.                 cmp dword[crop_r],ecx
  497.                 jge .24found_right
  498.  
  499.                 sub esi,3 ;двигаемся на 1-ну колонку влево
  500.                 mov ecx,buf2d_h ;восстановление ecx для нового цикла
  501.                 @@:
  502.                         add esi,ebx ;прыгаем на нижнюю строку
  503.                         cmp word[esi],ax
  504.                         jne .24found_right
  505.                         cmp byte[esi+2],dl
  506.                         jne .24found_right
  507.                         loop @b
  508.                 inc dword[crop_r]
  509.  
  510.                 mov ecx,buf2d_w
  511.                 dec ecx ;1 колонка на запас
  512.                 cmp dword[crop_r],ecx
  513.                 jl .24found_beg_right
  514.  
  515.                 .24found_right:
  516.                 cmp dword[crop_r],0
  517.                 je .24no_crop_right
  518.                         mov ecx,buf2d_w
  519.                         sub ecx,dword[crop_r]
  520.                         stdcall img_rgb_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
  521.                         mov buf2d_w,ecx ;ставим новую ширину для буфера
  522.                         mov ebx,buf2d_h
  523.                         imul ecx,ebx
  524.                         lea ecx,[ecx+ecx*2]
  525.                         invoke mem.realloc,buf2d_data,ecx
  526.                         mov buf2d_data,eax ;на случай если изменился указатель на данные
  527.         .24no_crop_right:
  528.  
  529.         bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
  530.         jae .24no_crop_left
  531.                 mov eax,dword[color]
  532.                 mov edx,eax ;ax = colors - r,g
  533.                 shr edx,16 ;dl = color - b
  534.                 mov ebx,buf2d_w
  535.                 cmp ebx,1
  536.                 jle .24no_crop_left ;на случай если ширина буфера 1 пиксель
  537.                 lea ebx,[ebx+ebx*2]
  538.                 mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
  539.                 mov dword[crop_r],0
  540.                 cld
  541.                 .24found_beg_left:
  542.  
  543.                 mov ecx,buf2d_h ;восстановление ecx для нового цикла
  544.                 @@:
  545.                         cmp word[esi],ax
  546.                         jne .24found_left
  547.                         cmp byte[esi+2],dl
  548.                         jne .24found_left
  549.                         add esi,ebx ;прыгаем на нижнюю строку
  550.                         loop @b
  551.                 inc dword[crop_r]
  552.                 add esi,3 ;двигаемся на 1-ну колонку вправо
  553.  
  554.                 mov ecx,buf2d_w
  555.                 dec ecx ;1 колонка на запас
  556.                 cmp dword[crop_r],ecx
  557.                 jge .24found_left
  558.  
  559.                 mov ecx,buf2d_h ;восстановление ecx для нового цикла
  560.                 @@:
  561.                         sub esi,ebx ;прыгаем на верхнюю строку
  562.                         cmp word[esi],ax
  563.                         jne .24found_left
  564.                         cmp byte[esi+2],dl
  565.                         jne .24found_left
  566.                         loop @b
  567.                 inc dword[crop_r]
  568.                 add esi,3 ;двигаемся на 1-ну колонку вправо
  569.  
  570.                 mov ecx,buf2d_w
  571.                 dec ecx ;1 колонка на запас
  572.                 cmp dword[crop_r],ecx
  573.                 jl .24found_beg_left
  574.  
  575.                 .24found_left:
  576.                 cmp dword[crop_r],0
  577.                 je .24no_crop_left
  578.                         mov ecx,buf2d_w
  579.                         sub ecx,dword[crop_r]
  580.                         stdcall img_rgb_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
  581.                         mov buf2d_w,ecx ;ставим новую ширину для буфера
  582.                         mov ebx,buf2d_h
  583.                         imul ecx,ebx
  584.                         lea ecx,[ecx+ecx*2]
  585.                         invoke mem.realloc,buf2d_data,ecx
  586.                         mov buf2d_data,eax ;на случай если изменился указатель на данные
  587.                         mov eax,dword[crop_r]
  588.                         add buf2d_l,ax
  589.         .24no_crop_left:
  590.  
  591.         .24end_f:
  592.  
  593.  
  594.         cmp buf2d_bits,8
  595.         jne .8end_f
  596.  
  597.         bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
  598.         jae .8no_crop_bottom
  599.                 mov eax,dword[color]
  600.                 mov esi,buf2d_data
  601.                 mov ecx,buf2d_h
  602.                 cmp ecx,1
  603.                 jle .8no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
  604.                 mov ebx,buf2d_w
  605.                 imul ecx,ebx
  606.                 mov esi,ecx
  607.                 add esi,buf2d_data
  608.                 cld
  609.                 @@:
  610.                         dec esi
  611.                         cmp byte[esi],al
  612.                         jne @f
  613.                         loop @b
  614.                 @@:
  615.                 xor edx,edx
  616.                 mov eax,buf2d_h
  617.                 imul eax,ebx
  618.                 add eax,buf2d_data ;eax - указатель на конец буфера изображения
  619.                 @@:
  620.                         add esi,ebx
  621.                         cmp esi,eax
  622.                         jge @f
  623.                         inc edx
  624.                         loop @b
  625.                 @@:
  626.                 cmp edx,0
  627.                 je .8no_crop_bottom
  628.                         cmp edx,buf2d_h
  629.                         jge .8no_crop_bottom ;что-бы не получить пустой буфер
  630.                         sub buf2d_h,edx ;уменьшаем высоту буфера
  631.                         mov ecx,buf2d_h
  632.                         imul ecx,ebx ;ecx = новый размер изображения
  633.                         invoke mem.realloc,buf2d_data,ecx
  634.                         mov buf2d_data,eax ;на случай если изменился указатель на данные
  635.         .8no_crop_bottom:
  636.  
  637.         bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
  638.         jae .8no_crop_top
  639.                 mov eax,dword[color]
  640.                 mov esi,buf2d_data
  641.                 mov ecx,buf2d_h
  642.                 cmp ecx,1
  643.                 jle .8no_crop_top ;проверяем на случай если высота буфера 1 пиксель
  644.                 dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
  645.                 mov ebx,buf2d_w
  646.                 imul ecx,ebx
  647.                 cld
  648.                 @@:
  649.                         cmp byte[esi],al
  650.                         jne @f
  651.                         inc esi
  652.                         loop @b
  653.                 @@:
  654.                 xor edx,edx
  655.                 @@:
  656.                         sub esi,ebx
  657.                         cmp esi,buf2d_data
  658.                         jl @f
  659.                         inc edx
  660.                         loop @b
  661.                 @@:
  662.                 cmp edx,0
  663.                 je .8no_crop_top
  664.                         xor eax,eax
  665.                         sub eax,edx
  666.                         mov ebx,buf2d_h
  667.                         sub ebx,edx
  668.                         stdcall buf_offset_h, edi, eax, edx, ebx
  669.                         mov ecx,buf2d_h
  670.                         sub ecx,edx
  671.                         mov buf2d_h,ecx ;уменьшаем высоту буфера
  672.                         add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
  673.                         mov ebx,buf2d_w
  674.                         imul ecx,ebx
  675.                         invoke mem.realloc,buf2d_data,ecx
  676.                         mov buf2d_data,eax ;на случай если изменился указатель на данные
  677.         .8no_crop_top:
  678.  
  679.         bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
  680.         jae .8no_crop_right
  681.                 mov eax,dword[color]
  682.                 mov ebx,buf2d_w
  683.                 cmp ebx,1
  684.                 jle .8no_crop_right ;на случай если ширина буфера 1 пиксель
  685.                 mov esi,ebx
  686.                 imul esi,buf2d_h
  687.                 add esi,buf2d_data ;esi - указатель на конец буфера изображения
  688.                 xor edx,edx
  689.                 cld
  690.  
  691.                 .8found_beg:
  692.                 dec esi ;двигаемся на 1-ну колонку влево
  693.                 mov ecx,buf2d_h ;восстановление ecx для нового цикла
  694.                 @@:
  695.                         cmp byte[esi],al
  696.                         jne .8found
  697.                         sub esi,ebx ;прыгаем на верхнюю строку
  698.                         loop @b
  699.                 inc edx
  700.                 mov ecx,buf2d_w
  701.                 dec ecx ;1 колонка на запас
  702.                 cmp edx,ecx
  703.                 jge .8found
  704.  
  705.                 dec esi ;двигаемся на 1-ну колонку влево
  706.                 mov ecx,buf2d_h ;восстановление ecx для нового цикла
  707.                 @@:
  708.                         add esi,ebx ;прыгаем на нижнюю строку
  709.                         cmp byte[esi],al
  710.                         jne .8found
  711.                         loop @b
  712.                 inc edx
  713.  
  714.                 mov ecx,buf2d_w
  715.                 dec ecx ;1 колонка на запас
  716.                 cmp edx,ecx
  717.                 jl .8found_beg
  718.  
  719.                 .8found:
  720.                 cmp edx,0
  721.                 je .8no_crop_right
  722.                         mov ecx,buf2d_w
  723.                         sub ecx,edx
  724.                         stdcall img_gray_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
  725.                         mov buf2d_w,ecx ;ставим новую ширину для буфера
  726.                         mov ebx,buf2d_h
  727.                         imul ecx,ebx
  728.                         invoke mem.realloc,buf2d_data,ecx
  729.                         mov buf2d_data,eax ;на случай если изменился указатель на данные
  730.         .8no_crop_right:
  731.  
  732.         bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
  733.         jae .8no_crop_left
  734.                 mov eax,dword[color]
  735.                 mov ebx,buf2d_w
  736.                 cmp ebx,1
  737.                 jle .8no_crop_left ;на случай если ширина буфера 1 пиксель
  738.                 mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
  739.                 mov edx,0
  740.                 cld
  741.                 .8found_beg_left:
  742.  
  743.                 mov ecx,buf2d_h ;восстановление ecx для нового цикла
  744.                 @@:
  745.                         cmp word[esi],ax
  746.                         jne .8found_left
  747.                         add esi,ebx ;прыгаем на нижнюю строку
  748.                         loop @b
  749.                 inc edx
  750.                 inc esi ;двигаемся на 1-ну колонку вправо
  751.  
  752.                 mov ecx,buf2d_w
  753.                 dec ecx ;1 колонка на запас
  754.                 cmp edx,ecx
  755.                 jge .8found_left
  756.  
  757.                 mov ecx,buf2d_h ;восстановление ecx для нового цикла
  758.                 @@:
  759.                         sub esi,ebx ;прыгаем на верхнюю строку
  760.                         cmp word[esi],ax
  761.                         jne .8found_left
  762.                         loop @b
  763.                 inc edx
  764.                 inc esi ;двигаемся на 1-ну колонку вправо
  765.  
  766.                 mov ecx,buf2d_w
  767.                 dec ecx ;1 колонка на запас
  768.                 cmp edx,ecx
  769.                 jl .8found_beg_left
  770.  
  771.                 .8found_left:
  772.                 cmp edx,0
  773.                 je .8no_crop_left
  774.                         mov ecx,buf2d_w
  775.                         sub ecx,edx
  776.                         stdcall img_gray_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
  777.                         mov buf2d_w,ecx ;ставим новую ширину для буфера
  778.                         mov ebx,buf2d_h
  779.                         imul ecx,ebx
  780.                         invoke mem.realloc,buf2d_data,ecx
  781.                         mov buf2d_data,eax ;на случай если изменился указатель на данные
  782.                         mov eax,edx
  783.                         add buf2d_l,ax
  784.         .8no_crop_left:
  785.  
  786.         .8end_f:
  787.  
  788.         popad
  789.         ret
  790. endp
  791.  
  792. ;обрезаем цветное изображение с правой стороны
  793. ;input:
  794. ;data_rgb - pointer to rgb data
  795. ;size_w_old - width img in pixels
  796. ;size_w_new - new width img in pixels
  797. ;size_h - height img in pixels
  798. align 4
  799. proc img_rgb_crop_r, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
  800.         pushad
  801.         mov eax, dword[size_w_old]
  802.         lea eax, dword[eax+eax*2] ;eax = width(old) * 3(rgb)
  803.         mov ebx, dword[size_w_new]
  804.         lea ebx, dword[ebx+ebx*2] ;ebx = width(new) * 3(rgb)
  805.         mov edx, dword[size_h]
  806.         mov edi, dword[data_rgb] ;edi - получает данные
  807.         mov esi, edi
  808.         add edi, ebx
  809.         add esi, eax
  810.         cld
  811.         @@:
  812.                 dec edx ;уменьшаем счетчик оставшихся строк на 1
  813.                 cmp edx,0
  814.                 jle @f
  815.                 mov ecx, ebx
  816.                 rep movsb ;перенос (копирование) строки пикселей
  817.                 add esi,eax ;переход на новую строчку изображения
  818.                 sub esi,ebx
  819.                 jmp @b
  820.         @@:
  821.         popad
  822.         ret
  823. endp
  824.  
  825. ;обрезаем серое изображение с правой стороны
  826. ;input:
  827. ;data_gray - pointer to gray data
  828. ;size_w_old - width img in pixels
  829. ;size_w_new - new width img in pixels
  830. ;size_h - height img in pixels
  831. align 4
  832. proc img_gray_crop_r, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
  833.         pushad
  834.         mov eax, dword[size_w_old]
  835.         mov ebx, dword[size_w_new]
  836.         mov edx, dword[size_h]
  837.         mov edi, dword[data_gray] ;edi - получает данные
  838.         mov esi, edi
  839.         add edi, ebx
  840.         add esi, eax
  841.         cld
  842.         @@:
  843.                 dec edx ;уменьшаем счетчик оставшихся строк на 1
  844.                 cmp edx,0
  845.                 jle @f
  846.                 mov ecx, ebx
  847.                 rep movsb ;перенос (копирование) строки пикселей
  848.                 add esi,eax ;переход на новую строчку изображения
  849.                 sub esi,ebx
  850.                 jmp @b
  851.         @@:
  852.         popad
  853.         ret
  854. endp
  855.  
  856. ;обрезаем цветное изображение с левой стороны
  857. ;input:
  858. ;data_rgb - pointer to rgb data
  859. ;size_w_old - width img in pixels
  860. ;size_w_new - new width img in pixels
  861. ;size_h - height img in pixels
  862. align 4
  863. proc img_rgb_crop_l, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
  864.         pushad
  865.         mov edi,dword[data_rgb]
  866.         mov esi,edi
  867.         mov eax,dword[size_w_old]
  868.         mov ebx,dword[size_w_new]
  869.         cmp eax,ebx
  870.         jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
  871.                 lea eax,[eax+eax*2]
  872.                 lea ebx,[ebx+ebx*2]
  873.                 sub eax,ebx
  874.                 mov edx,dword[size_h] ;высота изображения
  875.                 cld
  876.                 @@:
  877.                         add esi,eax
  878.                         mov ecx,ebx
  879.                         rep movsb
  880.                         dec edx
  881.                         cmp edx,0
  882.                         jg @b
  883.         .end_f:
  884.         popad
  885.         ret
  886. endp
  887.  
  888. ;обрезаем серое изображение с левой стороны
  889. ;input:
  890. ;data_gray - pointer to gray data
  891. ;size_w_old - width img in pixels
  892. ;size_w_new - new width img in pixels
  893. ;size_h - height img in pixels
  894. align 4
  895. proc img_gray_crop_l, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
  896.         pushad
  897.         mov edi,dword[data_gray]
  898.         mov esi,edi
  899.         mov eax,dword[size_w_old]
  900.         mov ebx,dword[size_w_new]
  901.         cmp eax,ebx
  902.         jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
  903.                 sub eax,ebx
  904.                 mov edx,dword[size_h] ;высота изображения
  905.                 cld
  906.                 @@:
  907.                         add esi,eax
  908.                         mov ecx,ebx
  909.                         rep movsb
  910.                         dec edx
  911.                         cmp edx,0
  912.                         jg @b
  913.         .end_f:
  914.         popad
  915.         ret
  916. endp
  917.  
  918. ;hoffs - колличество пикселей на котрые поднимается/опускается изображение
  919. ;img_t - высота, с которой начинается двигающаяся часть изображения
  920. align 4
  921. proc buf_offset_h, buf_struc:dword, hoffs:dword, img_t:dword, img_h:dword ;сдвигает изображение по высоте
  922.         pushad
  923.         mov edi,dword[buf_struc]
  924.         cmp buf2d_bits,24
  925.         jne .end_move_24
  926.  
  927.         mov eax,[hoffs]
  928.         cmp eax,0
  929.         je .end_move_24
  930.                 mov ebx,buf2d_w
  931.                 mov edx,dword[img_t]
  932.                         mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
  933.                         cmp ecx,buf2d_h
  934.                         jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
  935.                         imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
  936.                         lea ecx,[ecx+ecx*2]
  937.                 imul ebx,edx
  938.                 lea ebx,[ebx+ebx*2]
  939.                 mov esi,buf2d_data
  940.                 add esi,ebx
  941.  
  942.                 add edx,eax ;edx = img_t+hoffs (hoffs<0)
  943.                 mov ebx,buf2d_w
  944.                 imul ebx,edx
  945.                 lea ebx,[ebx+ebx*2]
  946.                 mov edi,buf2d_data ;позиция, куда будет двигаться изображение
  947.                 add edi,ebx
  948.  
  949.                 cmp eax,0
  950.                 jg .move_down_24
  951.                         ;двигаем изображение вверх
  952.                         cld
  953.                         rep movsb
  954.                         jmp .end_f
  955.                 .move_down_24:
  956.                         ;двигаем изображение вниз
  957.                         add esi,ecx
  958.                         dec esi
  959.                         add edi,ecx
  960.                         dec edi
  961.                         std
  962.                         rep movsb
  963.                         jmp .end_f
  964.         .end_move_24:
  965.  
  966. ;stdcall print_err,sz_buf2d_offset_h,txt_err_n24b
  967.  
  968.         cmp buf2d_bits,8
  969.         jne .end_move_8
  970.  
  971.         mov eax,[hoffs]
  972.         cmp eax,0
  973.         je .end_move_8
  974.                 ;двигаем изображение вверх
  975.                 mov ebx,buf2d_w
  976.                 mov edx,dword[img_t]
  977.                         mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
  978.                         cmp ecx,buf2d_h
  979.                         jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
  980.                         imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
  981.                 imul ebx,edx
  982.                 mov esi,buf2d_data
  983.                 add esi,ebx
  984.  
  985.                 add edx,eax ;edx = img_t+hoffs (hoffs<0)
  986.                 mov ebx,buf2d_w
  987.                 imul ebx,edx
  988.                 mov edi,buf2d_data ;позиция, куда будет двигаться изображение
  989.                 add edi,ebx
  990.  
  991.                 cmp eax,0
  992.                 jg .move_down_8
  993.                         cld
  994.                         rep movsb
  995.                         jmp .end_f
  996.                 .move_down_8:
  997.                         ;двигаем изображение вниз
  998.                         add esi,ecx
  999.                         dec esi
  1000.                         add edi,ecx
  1001.                         dec edi
  1002.                         std
  1003.                         rep movsb
  1004.                         jmp .end_f
  1005.         .end_move_8:
  1006.  
  1007.         .end_f:
  1008.         popad
  1009.         ret
  1010. endp
  1011.  
  1012.  
  1013. align 4
  1014. proc buf_draw_buf, buf_struc:dword
  1015.         pushad
  1016.         mov edi,dword[buf_struc]
  1017.         cmp buf2d_bits,24
  1018.         jne .error
  1019.                 mov eax,7
  1020.                 mov ebx,buf2d_data
  1021.  
  1022.                 mov ecx,buf2d_w
  1023.                 ror ecx,16
  1024.                 mov edx,buf2d_h
  1025.                 mov cx,dx
  1026.  
  1027.                 mov edx,buf2d_size_lt
  1028.                 ror edx,16
  1029.                 int 0x40
  1030.                 jmp .end_draw_24
  1031.         .error:
  1032.                 stdcall print_err,sz_buf2d_draw,txt_err_n24b
  1033.         .end_draw_24:
  1034.         popad
  1035.         ret
  1036. endp
  1037.  
  1038. align 4
  1039. proc buf_delete, buf_struc:dword
  1040.         push eax edi
  1041.         mov edi,dword[buf_struc]
  1042.         invoke mem.free,buf2d_data
  1043.         pop edi eax
  1044.         ret
  1045. endp
  1046.  
  1047. align 4
  1048. proc buf_resize, buf_struc:dword, new_w:dword, new_h:dword
  1049.         pushad
  1050.         mov edi,dword[buf_struc]
  1051.         cmp buf2d_bits,24
  1052.         jne .24bit
  1053.                 mov eax,dword[new_w]
  1054.                 cmp eax,1
  1055.                 jl @f
  1056.                         mov buf2d_w,eax
  1057.                 @@:
  1058.                 mov ecx,buf2d_w
  1059.                 mov eax,dword[new_h]
  1060.                 cmp eax,1
  1061.                 jl @f
  1062.                         mov buf2d_h,eax
  1063.                 @@:
  1064.                 mov ebx,buf2d_h
  1065.                 imul ecx,ebx
  1066.                 lea ecx,[ecx+ecx*2] ; 24 bit = 3
  1067.                 invoke mem.realloc,buf2d_data,ecx ;изменяем память занимаемую буфером
  1068.                 mov buf2d_data,eax ;на случай если изменился указатель на данные
  1069.         .24bit:
  1070.         popad
  1071.         ret
  1072. endp
  1073.  
  1074. align 4
  1075. rot_table: ;таблица для указания на подфункции для поворотов
  1076.         dd buf_rotate.8b90,buf_rotate.24b90,buf_rotate.32b90,\
  1077.         buf_rotate.8b180,buf_rotate.24b180,buf_rotate.32b180
  1078.  
  1079. ;поворот изображения на 90 или 180 градусов
  1080. align 4
  1081. proc buf_rotate, buf_struc:dword, angle:dword
  1082. locals
  1083.         n_data dd ?
  1084.         dec_h dd ? ;число байт, для уменьшения координаты y
  1085. endl
  1086.         pushad
  1087.         mov edi,[buf_struc]
  1088.         mov ebx,buf2d_w
  1089.         mov ecx,buf2d_h
  1090.  
  1091.         lea eax,[rot_table]
  1092.         cmp dword[angle],90 ;проверка угла поворота
  1093.         je .beg_0
  1094.         cmp dword[angle],180
  1095.         jne @f
  1096.                 add eax,12
  1097.                 jmp .beg_0
  1098.         @@:
  1099.         jmp .end_f
  1100.         .beg_0: ;проверка битности буфера
  1101.         cmp buf2d_bits,8
  1102.         jne @f
  1103.                 jmp dword[eax]
  1104.         @@:
  1105.         cmp buf2d_bits,24
  1106.         jne @f
  1107.                 add eax,4
  1108.                 jmp dword[eax]
  1109.         @@:
  1110.         cmp buf2d_bits,32
  1111.         jne @f
  1112.                 add eax,8
  1113.                 jmp dword[eax]
  1114.         @@:
  1115.         jmp .end_f
  1116.  
  1117.         .8b90: ;поворот 8 битного буфера на 90 градусов
  1118.                 mov edx,ecx ;edx - buf_h
  1119.                 imul ecx,ebx
  1120.                 invoke mem.alloc,ecx ;выделяем временную память
  1121.                 cmp eax,0
  1122.                 je .end_f
  1123.                 mov [n_data],eax
  1124.                 mov [dec_h],ecx
  1125.                 inc dword[dec_h]
  1126.  
  1127.                 ;copy buf --> mem
  1128.                 mov edi,[buf_struc]
  1129.                 mov esi,buf2d_data
  1130.                 mov edi,eax ;[n_data]
  1131.                 dec edx ;коректируем edx на 1 байт, для компенсации сдвига в movsb
  1132.                 add edi,edx
  1133.                 xor eax,eax
  1134.                 cld
  1135.                 .cycle_0:
  1136.                         movsb
  1137.                         add edi,edx
  1138.                         inc eax
  1139.                         cmp eax,ebx
  1140.                         jl @f
  1141.                                 xor eax,eax
  1142.                                 sub edi,[dec_h]
  1143.                         @@:
  1144.                         loop .cycle_0
  1145.  
  1146.                 ;change buf_w <---> buf_h
  1147.                 mov esi,[n_data]
  1148.                 mov edi,[buf_struc]
  1149.                 mov edi,buf2d_data
  1150.                 mov ecx,ebx
  1151.                 inc edx ;исправляем скоректированный edx
  1152.                 imul ecx,edx
  1153.                 ;copy buf <-- mem
  1154.                 ;cld
  1155.                 rep movsb
  1156.                 invoke mem.free,[n_data]
  1157.                 jmp .change_w_h
  1158.         .24b90: ;поворот 24 битного буфера на 90 градусов
  1159.                 mov esi,ecx
  1160.                 imul esi,ebx
  1161.                 lea ecx,[ecx+ecx*2]
  1162.                 mov edx,ecx ;edx - buf_h * 3
  1163.                 imul ecx,ebx
  1164.                 invoke mem.alloc,ecx ;выделяем временную память
  1165.                 cmp eax,0
  1166.                 je .end_f
  1167.                 mov [n_data],eax
  1168.                 mov [dec_h],ecx
  1169.                 add dword[dec_h],3
  1170.  
  1171.                 ;copy buf --> mem
  1172.                
  1173.                 mov edi,[buf_struc]
  1174.                 mov ecx,esi
  1175.                 mov esi,buf2d_data
  1176.                 mov edi,eax ;[n_data]
  1177.                 sub edx,3 ;коректируем edx на 3 байта, для компенсации сдвига
  1178.                 add edi,edx
  1179.                 xor eax,eax
  1180.                 cld
  1181.                 .cycle_1:
  1182.                         movsw
  1183.                         movsb
  1184.                         add edi,edx
  1185.                         inc eax
  1186.                         cmp eax,ebx
  1187.                         jl @f
  1188.                                 xor eax,eax
  1189.                                 sub edi,[dec_h]
  1190.                         @@:
  1191.                         loop .cycle_1
  1192.  
  1193.                 ;copy buf <-- mem
  1194.                 mov esi,[n_data]
  1195.                 mov edi,[buf_struc]
  1196.                 mov edi,buf2d_data
  1197.                 mov ecx,ebx
  1198.                 add edx,3 ;исправляем скоректированный edx
  1199.                 imul ecx,edx
  1200.                 ;cld
  1201.                 rep movsb
  1202.                 invoke mem.free,[n_data]
  1203.                 jmp .change_w_h
  1204.         .32b90: ;поворот 32 битного буфера на 90 градусов
  1205.                 shl ecx,2
  1206.                 mov edx,ecx ;edx - buf_h * 4
  1207.                 imul ecx,ebx
  1208.                 invoke mem.alloc,ecx ;выделяем временную память
  1209.                 cmp eax,0
  1210.                 je .end_f
  1211.                 mov [n_data],eax
  1212.                 mov [dec_h],ecx
  1213.                 add dword[dec_h],4
  1214.  
  1215.                 ;copy buf --> mem
  1216.                 mov edi,[buf_struc]
  1217.                 shr ecx,2
  1218.                 mov esi,buf2d_data
  1219.                 mov edi,eax ;[n_data]
  1220.                 sub edx,4 ;коректируем edx на 4 байта, для компенсации сдвига в movsd
  1221.                 add edi,edx
  1222.                 xor eax,eax
  1223.                 cld
  1224.                 .cycle_2:
  1225.                         movsd
  1226.                         add edi,edx
  1227.                         inc eax
  1228.                         cmp eax,ebx
  1229.                         jl @f
  1230.                                 xor eax,eax
  1231.                                 sub edi,[dec_h]
  1232.                         @@:
  1233.                         loop .cycle_2
  1234.  
  1235.                 ;copy buf <-- mem
  1236.                 mov esi,[n_data]
  1237.                 mov edi,[buf_struc]
  1238.                 mov edi,buf2d_data
  1239.                 mov ecx,ebx
  1240.                 add edx,4 ;исправляем скоректированный edx
  1241.                 imul ecx,edx
  1242.                 shr ecx,2
  1243.                 ;cld
  1244.                 rep movsd
  1245.                 invoke mem.free,[n_data]
  1246.                 ;jmp .change_w_h
  1247.         .change_w_h: ;change buf_w <---> buf_h
  1248.                 mov edi,[buf_struc]
  1249.                 mov eax,buf2d_w
  1250.                 mov ebx,buf2d_h
  1251.                 mov buf2d_h,eax
  1252.                 mov buf2d_w,ebx
  1253.                 jmp .end_f
  1254.         .8b180: ;поворот 8 битного буфера на 180 градусов
  1255.                 mov edi,buf2d_data
  1256.                 mov esi,edi
  1257.                 imul ecx,ebx
  1258.                 add esi,ecx
  1259.                 dec esi
  1260.                 shr ecx,1 ;ecx - число пикселей буфера : 2
  1261.                 std
  1262.                 @@:
  1263.                         lodsb
  1264.                         mov ah,byte[edi]
  1265.                         mov byte[esi+1],ah
  1266.                         mov byte[edi],al
  1267.                         inc edi
  1268.                         loop @b
  1269.                         jmp .end_f
  1270.         .24b180: ;поворот 24 битного буфера на 180 градусов
  1271.                 mov esi,buf2d_data
  1272.                 mov edi,esi
  1273.                 imul ecx,ebx
  1274.                 mov eax,ecx
  1275.                 lea ecx,[ecx+ecx*2]
  1276.                 add edi,ecx
  1277.                 sub edi,3
  1278.                 shr eax,1
  1279.                 mov ecx,eax ;ecx - число пикселей буфера : 2
  1280.                 cld
  1281.                 @@:
  1282.                         lodsw
  1283.                         mov edx,eax
  1284.                         lodsb
  1285.                         mov bx,word[edi]
  1286.                         mov word[esi-3],bx
  1287.                         mov bl,byte[edi+2]
  1288.                         mov byte[esi-1],bl
  1289.                         mov byte[edi+2],al
  1290.                         mov word[edi],dx
  1291.                         sub edi,3
  1292.                         loop @b
  1293.                         jmp .end_f
  1294.         .32b180: ;поворот 32 битного буфера на 180 градусов
  1295.                 mov edi,buf2d_data
  1296.                 mov esi,edi
  1297.                 imul ecx,ebx
  1298.                 shl ecx,2
  1299.                 add esi,ecx
  1300.                 sub esi,4
  1301.                 shr ecx,3 ;ecx - число пикселей буфера : 2
  1302.                 std
  1303.                 @@:
  1304.                         lodsd
  1305.                         mov ebx,dword[edi]
  1306.                         mov dword[esi+4],ebx
  1307.                         mov dword[edi],eax
  1308.                         add edi,4
  1309.                         loop @b
  1310.                 ;jmp .end_f
  1311.  
  1312.         .end_f:
  1313.         popad
  1314.         ret
  1315. endp
  1316.  
  1317. align 4
  1318. proc buf_line_brs, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
  1319. locals
  1320.         loc_1 dd ?
  1321.         loc_2 dd ?
  1322.         napravl db ?
  1323. endl
  1324.         pushad
  1325.                 mov eax,dword[coord_x1]
  1326.                 sub eax,dword[coord_x0]
  1327.                 bt eax,31
  1328.                 jae @f
  1329.                         neg eax
  1330.                         inc eax
  1331.                 @@:
  1332.                 mov ebx,dword[coord_y1]
  1333.                 sub ebx,dword[coord_y0]
  1334.                 jnz @f
  1335.                         ;если задана горизонтальная линия y0=y1
  1336.                         stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
  1337.                         jmp .coord_end
  1338.                 @@:
  1339.                 bt ebx,31
  1340.                 jae @f
  1341.                         neg ebx
  1342.                         inc ebx
  1343.                 @@:
  1344.                 mov edx,dword[color]
  1345.  
  1346.                 mov [napravl],byte 0 ;bool steep=false
  1347.                 cmp eax,ebx
  1348.                 jle @f
  1349.                         mov [napravl],byte 1 ;bool steep=true
  1350.                         swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
  1351.                         swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
  1352.                 @@:
  1353.                 mov eax,dword[coord_y0] ;x0
  1354.                 cmp eax,dword[coord_y1] ;if(x0>x1)
  1355.                 jle @f
  1356.                         swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
  1357.                         swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
  1358.                 @@:
  1359.  
  1360. ; int deltax esi
  1361. ; int deltay edi
  1362. ; int error  ebp-6
  1363. ; int ystep  ebp-8
  1364.  
  1365.                 mov eax,dword[coord_y0]
  1366.                 mov esi,dword[coord_y1]
  1367.                 sub esi,eax ;deltax = y1-y0
  1368.                 mov ebx,esi
  1369.                 shr ebx,1
  1370.                 mov [loc_1],ebx ;error = deltax/2
  1371.  
  1372.                 mov eax,dword[coord_x0]
  1373.                 mov edi,dword[coord_x1]
  1374.                 mov [loc_2],dword -1 ;ystep = -1
  1375.                 cmp eax,edi ;if (x0<x1) ystep = 1;
  1376.                 jge @f
  1377.                         mov [loc_2],dword 1 ;ystep = 1
  1378.                 @@:
  1379.                 sub edi,eax ;x1-x0
  1380.  
  1381.                 bts edi,31
  1382.                 jae @f
  1383.                         neg edi
  1384.                         inc edi
  1385.                 @@:
  1386.                 and edi,0x7fffffff ;deltay = abs(x1-x0)
  1387.  
  1388.                 mov eax,edi
  1389.                 mov edi,[buf_struc]
  1390.                 cmp buf2d_bits,8
  1391.                 je @f
  1392.                 cmp buf2d_bits,24
  1393.                 je @f
  1394.                         jmp .coord_end
  1395.                 @@:
  1396.  
  1397.                 cmp [napravl],0
  1398.                 jne .coord_yx
  1399.                         mov ebx,dword[coord_x0]
  1400.                         mov ecx,dword[coord_y0]
  1401.  
  1402.                         @@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
  1403.                                 cmp ecx,dword[coord_y1]
  1404.                                 jg @f ;jge ???
  1405.                                 call draw_pixel
  1406.  
  1407.                                 sub dword[loc_1],eax ;error -= deltay
  1408.                                 cmp dword[loc_1],0 ;if(error<0)
  1409.                                 jge .if0
  1410.                                         add ebx,[loc_2] ;y += ystep
  1411.                                         add [loc_1],esi ;error += deltax
  1412.                                 .if0:
  1413.                                 inc ecx
  1414.                                 jmp @b
  1415.                         @@:
  1416.                         jmp .coord_end
  1417.                 .coord_yx:
  1418.                         mov ebx,dword[coord_y0]
  1419.                         mov ecx,dword[coord_x0]
  1420.  
  1421.                         @@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
  1422.                                 cmp ebx,dword[coord_y1]
  1423.                                 jg @f ;jge ???
  1424.                                 call draw_pixel
  1425.  
  1426.                                 sub dword[loc_1],eax ;error -= deltay
  1427.                                 cmp dword[loc_1],0 ;if(error<0)
  1428.                                 jge .if1
  1429.                                         add ecx,[loc_2] ;y += ystep
  1430.                                         add [loc_1],esi ;error += deltax
  1431.                                 .if1:
  1432.                                 inc ebx
  1433.                                 jmp @b
  1434.                         @@:
  1435.         .coord_end:
  1436.         popad
  1437.         ret
  1438. endp
  1439.  
  1440. ;рисование сглаженной линии
  1441. align 4
  1442. proc buf_line_brs_sm, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
  1443. locals
  1444.         loc_1 dd ?
  1445.         loc_2 dd ?
  1446.         napravl db ?
  1447. endl
  1448.         pushad
  1449.                 mov eax,dword[coord_x1]
  1450.                 sub eax,dword[coord_x0]
  1451.                 bt eax,31
  1452.                 jae @f
  1453.                         neg eax
  1454.                         inc eax
  1455.                 @@:
  1456.                 mov ebx,dword[coord_y1]
  1457.                 sub ebx,dword[coord_y0]
  1458.                 jnz @f
  1459.                         ;если задана горизонтальная линия y0=y1
  1460.                         stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
  1461.                         jmp .coord_end
  1462.                 @@:
  1463.                 bt ebx,31
  1464.                 jae @f
  1465.                         neg ebx
  1466.                         inc ebx
  1467.                 @@:
  1468.                 mov edx,dword[color]
  1469.  
  1470.                 mov [napravl],byte 0 ;bool steep=false
  1471.                 cmp eax,ebx
  1472.                 jle @f
  1473.                         mov [napravl],byte 1 ;bool steep=true
  1474.                         swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
  1475.                         swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
  1476.                 @@:
  1477.                 mov eax,dword[coord_y0] ;x0
  1478.                 cmp eax,dword[coord_y1] ;if(x0>x1)
  1479.                 jle @f
  1480.                         swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
  1481.                         swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
  1482.                 @@:
  1483.  
  1484. ; int deltax esi
  1485. ; int deltay edi
  1486. ; int error  ebp-6
  1487. ; int ystep  ebp-8
  1488.  
  1489.                 mov eax,dword[coord_y0]
  1490.                 mov esi,dword[coord_y1]
  1491.                 sub esi,eax ;deltax = y1-y0
  1492.                 mov ebx,esi
  1493.                 shr ebx,1
  1494.                 mov [loc_1],ebx ;error = deltax/2
  1495.  
  1496.                 mov eax,dword[coord_x0]
  1497.                 mov edi,dword[coord_x1]
  1498.                 mov [loc_2],dword -1 ;ystep = -1
  1499.                 cmp eax,edi ;if (x0<x1) ystep = 1;
  1500.                 jge @f
  1501.                         mov [loc_2],dword 1 ;ystep = 1
  1502.                 @@:
  1503.                 sub edi,eax ;x1-x0
  1504.  
  1505.                 bts edi,31
  1506.                 jae @f
  1507.                         neg edi
  1508.                         inc edi
  1509.                 @@:
  1510.                 and edi,0x7fffffff ;deltay = abs(x1-x0)
  1511.  
  1512.                 mov eax,edi
  1513.                 mov edi,[buf_struc]
  1514.                 cmp buf2d_bits,24
  1515.                 jne .coord_end
  1516.  
  1517.                 cmp [napravl],0
  1518.                 jne .coord_yx
  1519.                         mov ebx,dword[coord_x0]
  1520.                         mov ecx,dword[coord_y0]
  1521.  
  1522.                         @@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
  1523.                                 cmp ecx,dword[coord_y1]
  1524.                                 jg @f ;jge ???
  1525.                                 push eax
  1526.                                         mov eax,esi
  1527.                                         sub eax,[loc_1]
  1528.                                         stdcall draw_pixel_transp, eax,esi
  1529.                                 pop eax
  1530.                                 add ebx,[loc_2]
  1531.                                 stdcall draw_pixel_transp, [loc_1],esi
  1532.                                 sub ebx,[loc_2]
  1533.  
  1534.                                 sub dword[loc_1],eax ;error -= deltay
  1535.                                 cmp dword[loc_1],0 ;if(error<0)
  1536.                                 jge .if0
  1537.                                         add ebx,[loc_2] ;y += ystep
  1538.                                         add [loc_1],esi ;error += deltax
  1539.                                 .if0:
  1540.                                 inc ecx
  1541.                                 jmp @b
  1542.                         @@:
  1543.                         jmp .coord_end
  1544.                 .coord_yx:
  1545.                         mov ebx,dword[coord_y0]
  1546.                         mov ecx,dword[coord_x0]
  1547.  
  1548.                         @@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
  1549.                                 cmp ebx,dword[coord_y1]
  1550.                                 jg @f ;jge ???
  1551.                                 push eax
  1552.                                         mov eax,esi
  1553.                                         sub eax,[loc_1]
  1554.                                         stdcall draw_pixel_transp, eax,esi
  1555.                                 pop eax
  1556.                                 add ecx,[loc_2]
  1557.                                 stdcall draw_pixel_transp, [loc_1],esi
  1558.                                 sub ecx,[loc_2]
  1559.  
  1560.                                 sub dword[loc_1],eax ;error -= deltay
  1561.                                 cmp dword[loc_1],0 ;if(error<0)
  1562.                                 jge .if1
  1563.                                         add ecx,[loc_2] ;y += ystep
  1564.                                         add [loc_1],esi ;error += deltax
  1565.                                 .if1:
  1566.                                 inc ebx
  1567.                                 jmp @b
  1568.                         @@:
  1569.         .coord_end:
  1570.         popad
  1571.         ret
  1572. endp
  1573.  
  1574. ;рисование горизонтальной линии, потому нет параметра coord_y1
  1575. align 4
  1576. proc buf_line_h, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, color:dword
  1577.         pushad
  1578.         pushfd
  1579.                 mov edi,[buf_struc]
  1580.                 cmp buf2d_bits,8
  1581.                 je @f
  1582.                 cmp buf2d_bits,24
  1583.                 je @f
  1584.                         jmp .end24
  1585.                 @@: ;определение координат линии относительно буфера
  1586.  
  1587.                 mov ecx,dword[coord_y0]
  1588.                 bt ecx,31
  1589.                 jc .end24 ;если координата y0 отрицательная
  1590.                 cmp ecx,buf2d_h
  1591.                 jge .end24 ;если координата y0 больше высоты буфера
  1592.  
  1593.                 mov ebx,dword[coord_x0]
  1594.                 mov esi,dword[coord_x1]
  1595.                 cmp ebx,esi
  1596.                 jle @f
  1597.                         xchg ebx,esi ;если x0 > x1 то меняем местами x0 и x1
  1598.                 @@:
  1599.                 bt ebx,31
  1600.                 jae @f
  1601.                         ;если координата x0 отрицательная
  1602.                         xor ebx,ebx
  1603.                 @@:
  1604.                 cmp esi,buf2d_w
  1605.                 jl @f
  1606.                         ;если координата x0 больше ширины буфера
  1607.                         mov esi,buf2d_w
  1608.                         dec esi
  1609.                 @@:
  1610.                 cmp ebx,esi
  1611.                 jg .end24 ;если x0 > x1 может возникнуть когда обе координаты x0, x1 находились за одним из пределов буфера
  1612.  
  1613.                 cmp buf2d_bits,24
  1614.                 je .beg24
  1615.                         ;рисование в 8 битном буфере
  1616.                         ;в edx вычисляем начало 1-й точки линии в буфере изображения
  1617.                         mov edx,buf2d_w ;size x
  1618.                         imul edx,ecx ;size_x*y
  1619.                         add edx,ebx      ;size_x*y+x
  1620.                         add edx,buf2d_data ;ptr+(size_x*y+x)
  1621.                         mov edi,edx ;теперь можем портить указатель на буфер
  1622.  
  1623.                         mov ecx,esi
  1624.                         sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
  1625.                         inc ecx ;что-бы последняя точка линии также отображалась
  1626.                         mov eax,dword[color] ;будем использовать только значение в al
  1627.                         cld
  1628.                         rep stosb ;цикл по оси x от x0 до x1 (включая x1)
  1629.                         jmp .end24
  1630.  
  1631.                 .beg24: ;рисование в 24 битном буфере
  1632.                 ;в eax вычисляем начало 1-й точки линии в буфере изображения
  1633.                 mov eax,buf2d_w ;size x
  1634.                 imul eax,ecx ;size_x*y
  1635.                 add eax,ebx      ;size_x*y+x
  1636.                 lea eax,[eax+eax*2] ;(size_x*y+x)*3
  1637.                 add eax,buf2d_data  ;ptr+(size_x*y+x)*3
  1638.  
  1639.                 mov ecx,esi
  1640.                 sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
  1641.                 inc ecx ;что-бы последняя точка линии также отображалась
  1642.                 mov edx,dword[color]
  1643.                 mov ebx,edx ;координата x0 в ebx уже не нужна
  1644.                 ror edx,16 ;поворачиваем регистр что бы 3-й байт попал в dl
  1645.                 cld
  1646.                 @@: ;цикл по оси x от x0 до x1 (включая x1)
  1647.                         mov word[eax],bx ;copy pixel color
  1648.                         mov byte[eax+2],dl
  1649.                         add eax,3
  1650.                         loop @b
  1651.                 .end24:
  1652.         popfd
  1653.         popad
  1654.         ret
  1655. endp
  1656.  
  1657. align 4
  1658. proc buf_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
  1659. pushad
  1660.         mov edi,[buf_struc]
  1661.         cmp buf2d_bits,8
  1662.         je @f
  1663.         cmp buf2d_bits,24
  1664.         je @f
  1665.                 jmp .coord_end
  1666.         @@:
  1667.  
  1668.                 mov eax,[coord_x]
  1669.                 mov ebx,[coord_y]
  1670.                 mov ecx,[w]
  1671.                 ;cmp ecx,1
  1672.                 ;jl .coord_end
  1673.                 cmp ecx,0
  1674.                 je .coord_end
  1675.                 jg @f
  1676.                         add eax,ecx
  1677.                         inc eax
  1678.                         neg ecx
  1679.                 @@:
  1680.                 add ecx,eax
  1681.                 dec ecx
  1682.                 mov edx,[h]
  1683.                 ;cmp edx,1
  1684.                 ;jl .coord_end
  1685.                 cmp edx,0
  1686.                 je .coord_end
  1687.                 jg @f
  1688.                         add ebx,edx
  1689.                         inc ebx
  1690.                         neg edx
  1691.                 @@:
  1692.  
  1693.                 add edx,ebx
  1694.                 dec edx
  1695.                 mov esi,dword[color]
  1696.                 stdcall buf_line_h, edi, eax, ebx, ecx, esi ;линия -
  1697.                 stdcall buf_line_brs, edi, eax, ebx, eax, edx, esi ;линия |
  1698.                 stdcall buf_line_h, edi, eax, edx, ecx, esi ;линия -
  1699.                 stdcall buf_line_brs, edi, ecx, ebx, ecx, edx, esi ;линия |
  1700.         .coord_end:
  1701. popad
  1702.         ret
  1703. endp
  1704.  
  1705. align 4
  1706. proc buf_filled_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
  1707. pushad
  1708.         mov edi,[buf_struc]
  1709.         cmp buf2d_bits,8
  1710.         je @f
  1711.         cmp buf2d_bits,24
  1712.         je @f
  1713.                 jmp .coord_end
  1714.         @@:
  1715.                 mov eax,[coord_x]
  1716.                 mov ebx,[coord_y]
  1717.                 mov edx,[w]
  1718.                 cmp edx,0
  1719.                 je .coord_end ;если высота 0 пикселей
  1720.                 jg @f ;если высота положительная
  1721.                         add eax,edx
  1722.                         inc eax
  1723.                         neg edx ;ширину делаем положительной
  1724.                         ;inc edx ;почему тут не добавляем 1-цу я не знаю, но с ней работает не правильно
  1725.                 @@:
  1726.                 add edx,eax
  1727.                 dec edx
  1728.                 mov ecx,[h]
  1729.                 cmp ecx,0
  1730.                 je .coord_end ;если высота 0 пикселей
  1731.                 jg @f ;если высота положительная
  1732.                         add ebx,ecx ;сдвигаем верхнюю координату прямоугольника
  1733.                         inc ebx
  1734.                         neg ecx ;высоту делаем положительной
  1735.                         ;inc ecx ;почему тут не добавляем 1-цу я не знаю, но с ней работает не правильно
  1736.                 @@:
  1737.                 mov esi,dword[color]
  1738.                 cld
  1739.                 @@:
  1740.                         stdcall buf_line_h, edi, eax, ebx, edx, esi ;линия -
  1741.                         inc ebx
  1742.                         loop @b
  1743.         .coord_end:
  1744. popad
  1745.         ret
  1746. endp
  1747.  
  1748. align 4
  1749. proc buf_circle, buf_struc:dword, coord_x:dword, coord_y:dword, r:dword, color:dword
  1750. locals
  1751.         po_x dd ?
  1752.         po_y dd ?
  1753. endl
  1754.         pushad
  1755.         mov edi,dword[buf_struc]
  1756.         cmp buf2d_bits,8
  1757.         je @f
  1758.         cmp buf2d_bits,24
  1759.         je @f
  1760.                 jmp .error
  1761.         @@:
  1762.                 mov edx,dword[color]
  1763.  
  1764.                 finit
  1765.                 fild dword[coord_x]
  1766.                 fild dword[coord_y]
  1767.                 fild dword[r]
  1768.                 fldz ;px=0
  1769.                 fld st1 ;py=r
  1770.  
  1771.                 fldpi
  1772.                 fmul st0,st3
  1773.                 fistp dword[po_x]
  1774.                 mov esi,dword[po_x] ;esi=pi*r
  1775.                 shl esi,1 ;esi=2*pi*r
  1776.  
  1777.                 ;st0 = py
  1778.                 ;st1 = px
  1779.                 ;st2 = r
  1780.                 ;st3 = y
  1781.                 ;st4 = x
  1782.  
  1783.                 @@:
  1784.                         ;Point(px + x, y - py)
  1785.                         fld st1 ;st0=px
  1786.                         fadd st0,st5 ;st0=px+x
  1787.                         fistp dword[po_x]
  1788.                         mov ebx,dword[po_x]
  1789.                         fld st3 ;st0=y
  1790.                         fsub st0,st1 ;st0=y-py
  1791.                         fistp dword[po_y]
  1792.                         mov ecx,dword[po_y]
  1793.                         call draw_pixel
  1794.                         ;px += py/r
  1795.                         fld st0 ;st0=py
  1796.                         fdiv st0,st3 ;st0=py/r
  1797.                         faddp st2,st0 ;st3+=st0
  1798.                         ;py -= px/r
  1799.                         fld st1 ;st0=px
  1800.                         fdiv st0,st3 ;st0=px/r
  1801.                         fsubp st1,st0 ;st2-=st0
  1802.  
  1803.                         dec esi
  1804.                         cmp esi,0
  1805.                         jge @b
  1806.                 jmp .exit_fun
  1807.         .error:
  1808.                 stdcall print_err,sz_buf2d_circle,txt_err_n8_24b
  1809.         .exit_fun:
  1810.  
  1811.         popad
  1812.         ret
  1813. endp
  1814.  
  1815. ;функция для заливки области выбранным цветом
  1816. align 4
  1817. proc buf_flood_fill, buf_struc:dword, coord_x:dword, coord_y:dword, mode:dword, color_f:dword, color_b:dword
  1818.         pushad
  1819.                 mov edi,[buf_struc]
  1820.                 cmp buf2d_bits,24
  1821.                 jne .end24
  1822.  
  1823.                         mov ebx,dword[coord_x]
  1824.                         mov ecx,dword[coord_y]
  1825.                         mov edx,dword[color_f]
  1826.                         mov esi,dword[color_b]
  1827.  
  1828.                         cmp dword[mode],1 ;в зависимости от 'mode' определяем каким алгоритмом будем пользоваться
  1829.                         je @f
  1830.                                 call buf_flood_fill_recurs_0 ;заливаем до пикселей цвета esi
  1831.                                 jmp .end24
  1832.                         @@:
  1833.                                 call buf_flood_fill_recurs_1 ;заливаем пиксели имеющие цвет esi
  1834.  
  1835.                 .end24:
  1836.         popad
  1837.         ret
  1838. endp
  1839.  
  1840. ;input:
  1841. ; ebx = coord_x
  1842. ; ecx = coord_y
  1843. ; edx = цвет заливки
  1844. ; esi = цвет границы, до которой будет ити заливка
  1845. ; edi = buf_struc
  1846. ;output:
  1847. ; eax = портится
  1848. align 4
  1849. buf_flood_fill_recurs_0:
  1850.         call get_pixel_24
  1851.         cmp eax,0xffffffff ;if error coords
  1852.         je .end_fun
  1853.         cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
  1854.         je .end_fun
  1855.  
  1856.                 call draw_pixel
  1857.  
  1858.                 dec ebx
  1859.                 call get_pixel_24
  1860.                 cmp eax,esi
  1861.                 je @f
  1862.                         call buf_flood_fill_recurs_0
  1863.                 @@:
  1864.                 inc ebx
  1865.  
  1866.  
  1867.                 inc ebx
  1868.                 call get_pixel_24
  1869.                 cmp eax,esi
  1870.                 je @f
  1871.                         call buf_flood_fill_recurs_0
  1872.                 @@:
  1873.                 dec ebx
  1874.  
  1875.                 dec ecx
  1876.                 call get_pixel_24
  1877.                 cmp eax,esi
  1878.                 je @f
  1879.                         call buf_flood_fill_recurs_0
  1880.                 @@:
  1881.                 inc ecx
  1882.  
  1883.                 inc ecx
  1884.                 call get_pixel_24
  1885.                 cmp eax,esi
  1886.                 je @f
  1887.                         call buf_flood_fill_recurs_0
  1888.                 @@:
  1889.                 dec ecx
  1890.  
  1891.         .end_fun:
  1892.         ret
  1893.  
  1894. ;input:
  1895. ; ebx = coord_x
  1896. ; ecx = coord_y
  1897. ; edx = цвет заливки
  1898. ; esi = цвет пикселей, по которым будет ити заливка
  1899. ; edi = buf_struc
  1900. ;output:
  1901. ; eax = портится
  1902. align 4
  1903. buf_flood_fill_recurs_1:
  1904.         call get_pixel_24
  1905.         cmp eax,0xffffffff ;if error coords
  1906.         je .end_fun
  1907.         cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
  1908.         je .end_fun
  1909.         cmp eax,esi ;если цвет пикселя не совпал с заливаемым цветом заливки, то прекращаем заливку
  1910.         jne .end_fun
  1911.  
  1912.                 call draw_pixel
  1913.  
  1914.                 dec ebx
  1915.                 call get_pixel_24
  1916.                 cmp eax,esi
  1917.                 jne @f
  1918.                         call buf_flood_fill_recurs_1
  1919.                 @@:
  1920.                 inc ebx
  1921.  
  1922.  
  1923.                 inc ebx
  1924.                 call get_pixel_24
  1925.                 cmp eax,esi
  1926.                 jne @f
  1927.                         call buf_flood_fill_recurs_1
  1928.                 @@:
  1929.                 dec ebx
  1930.  
  1931.                 dec ecx
  1932.                 call get_pixel_24
  1933.                 cmp eax,esi
  1934.                 jne @f
  1935.                         call buf_flood_fill_recurs_1
  1936.                 @@:
  1937.                 inc ecx
  1938.  
  1939.                 inc ecx
  1940.                 call get_pixel_24
  1941.                 cmp eax,esi
  1942.                 jne @f
  1943.                         call buf_flood_fill_recurs_1
  1944.                 @@:
  1945.                 dec ecx
  1946.  
  1947.         .end_fun:
  1948.         ret
  1949.  
  1950. ;функция для рисования точки
  1951. align 4
  1952. proc buf_set_pixel uses ebx ecx edx edi, buf_struc:dword, coord_x:dword, coord_y:dword, color:dword
  1953.         mov edi,dword[buf_struc]
  1954.         mov ebx,dword[coord_x]
  1955.         mov ecx,dword[coord_y]
  1956.         mov edx,dword[color]
  1957.         call draw_pixel
  1958.         ret
  1959. endp
  1960.  
  1961. ;output:
  1962. ; eax = цвет точки
  1963. ; в случае ошибки eax = 0xffffffff
  1964. align 4
  1965. proc buf_get_pixel uses ebx ecx edi, buf_struc:dword, coord_x:dword, coord_y:dword
  1966.         mov edi,dword[buf_struc]
  1967.         mov ebx,[coord_x]
  1968.         mov ecx,[coord_y]
  1969.  
  1970.         cmp buf2d_bits,8
  1971.         jne @f
  1972.                 call get_pixel_8
  1973.                 jmp .end_fun
  1974.         @@:
  1975.         cmp buf2d_bits,24
  1976.         jne @f
  1977.                 call get_pixel_24
  1978.                 jmp .end_fun
  1979.         @@:
  1980.         cmp buf2d_bits,32
  1981.         jne @f
  1982.                 call get_pixel_32
  1983.                 ;jmp .end_fun
  1984.         @@:
  1985.         .end_fun:
  1986.         ret
  1987. endp
  1988.  
  1989. ;отразить по вертикали (верх и низ меняются местами)
  1990. align 4
  1991. proc buf_flip_v, buf_struc:dword
  1992. locals
  1993.     line_pix dd ? ;кол. пикселей в линии буфера
  1994.     line_2byte dd ? ;кол. байт в линии буфера * 2
  1995. endl
  1996.         pushad
  1997.         mov edi,[buf_struc]
  1998.     cmp buf2d_bits,24
  1999.     jne .end_24
  2000.         mov edx,buf2d_w
  2001.         mov [line_pix],edx
  2002.         mov ebx,buf2d_h
  2003.         lea edx,[edx+edx*2]
  2004.         mov esi,edx
  2005.         imul esi,ebx
  2006.         sub esi,edx
  2007.         add esi,buf2d_data ;указатель на нижнюю линию
  2008.         shr ebx,1 ;кол. линейных циклов
  2009.         shl edx,1
  2010.         mov [line_2byte],edx
  2011.         mov edi,buf2d_data
  2012.         xchg edi,esi
  2013.         cld
  2014.         .flip_24:
  2015.         cmp ebx,0
  2016.         jle .end_24
  2017.         mov ecx,[line_pix]
  2018.         @@:
  2019.             lodsw
  2020.             mov dx,word[edi]
  2021.             mov word[esi-2],dx
  2022.             mov [edi],ax
  2023.             lodsb
  2024.             mov ah,byte[edi+2]
  2025.             mov byte[esi-1],ah
  2026.             mov [edi+2],al
  2027.             add edi,3
  2028.             loop @b
  2029.         sub edi,[line_2byte]
  2030.         dec ebx
  2031.         jmp .flip_24
  2032.     .end_24:
  2033.     popad
  2034.     ret
  2035. endp
  2036.  
  2037. align 4
  2038. proc buf_img_wdiv2, buf_struc:dword
  2039.         pushad
  2040.         mov edi,dword[buf_struc]
  2041.         cmp buf2d_bits,8
  2042.         jne @f
  2043.                 mov eax,buf2d_w
  2044.                 mov ecx,buf2d_h
  2045.                 imul ecx,eax
  2046.                 stdcall img_8b_wdiv2, buf2d_data,ecx
  2047.         @@:
  2048.         cmp buf2d_bits,24
  2049.         jne @f
  2050.                 mov eax,buf2d_w
  2051.                 mov ecx,buf2d_h
  2052.                 imul ecx,eax
  2053.                 stdcall img_rgb24_wdiv2, buf2d_data,ecx
  2054.         @@:
  2055.         cmp buf2d_bits,32
  2056.         jne @f
  2057.                 mov eax,buf2d_w
  2058.                 mov ecx,buf2d_h
  2059.                 imul ecx,eax
  2060.                 stdcall img_rgba32_wdiv2, buf2d_data,ecx
  2061.         @@:
  2062.         popad
  2063.         ret
  2064. endp
  2065.  
  2066. ;input:
  2067. ;data_8b - pointer to rgb data
  2068. ;size - count img pixels (size img data / 3(rgb) )
  2069. align 4
  2070. proc img_8b_wdiv2 data_8b:dword, size:dword
  2071.         mov eax,dword[data_8b]
  2072.         mov ecx,dword[size] ;ecx = size
  2073.         cld
  2074.         @@: ;затемнение цвета пикселей
  2075.                 shr byte[eax],1
  2076.                 inc eax
  2077.                 loop @b
  2078.  
  2079.         mov eax,dword[data_8b]
  2080.         mov ecx,dword[size] ;ecx = size
  2081.         shr ecx,1
  2082.         @@: ;сложение цветов пикселей
  2083.                 mov bl,byte[eax+1] ;копируем цвет соседнего пикселя
  2084.                 add byte[eax],bl
  2085.                 add eax,2
  2086.                 loop @b
  2087.  
  2088.         mov eax,dword[data_8b]
  2089.         inc eax
  2090.         mov ebx,eax
  2091.         inc ebx
  2092.         mov ecx,dword[size] ;ecx = size
  2093.         shr ecx,1
  2094.         dec ecx ;лишний пиксель
  2095.         @@: ;поджатие пикселей
  2096.                 mov dl,byte[ebx]
  2097.                 mov byte[eax],dl
  2098.  
  2099.                 inc eax
  2100.                 add ebx,2
  2101.                 loop @b
  2102.         ret
  2103. endp
  2104.  
  2105. ;input:
  2106. ;data_rgb - pointer to rgb data
  2107. ;size - count img pixels (size img data / 3(rgb) )
  2108. align 4
  2109. proc img_rgb24_wdiv2 data_rgb:dword, size:dword
  2110.   mov eax,dword[data_rgb]
  2111.   mov ecx,dword[size] ;ecx = size
  2112.   lea ecx,[ecx+ecx*2]
  2113.   cld
  2114.   @@: ;затемнение цвета пикселей
  2115.                 shr byte[eax],1
  2116.                 inc eax
  2117.                 loop @b
  2118.  
  2119.   mov eax,dword[data_rgb]
  2120.   mov ecx,dword[size] ;ecx = size
  2121.   shr ecx,1
  2122.   @@: ;сложение цветов пикселей
  2123.                 mov bx,word[eax+3] ;копируем цвет соседнего пикселя
  2124.                 add word[eax],bx
  2125.                 mov bl,byte[eax+5] ;копируем цвет соседнего пикселя
  2126.                 add byte[eax+2],bl
  2127.                 add eax,6 ;=2*3
  2128.                 loop @b
  2129.  
  2130.   mov eax,dword[data_rgb]
  2131.   add eax,3
  2132.   mov ebx,eax
  2133.   add ebx,3
  2134.   mov ecx,dword[size] ;ecx = size
  2135.   shr ecx,1
  2136.   dec ecx ;лишний пиксель
  2137.   @@: ;поджатие пикселей
  2138.                 mov edx,dword[ebx]
  2139.                 mov word[eax],dx
  2140.                 shr edx,16
  2141.                 mov byte[eax+2],dl
  2142.  
  2143.                 add eax,3
  2144.                 add ebx,6
  2145.                 loop @b
  2146.   ret
  2147. endp
  2148.  
  2149. ;input:
  2150. ;data_rgba - pointer to rgba data
  2151. ;size - count img pixels (size img data / 4(rgba) )
  2152. align 4
  2153. proc img_rgba32_wdiv2 data_rgba:dword, size:dword
  2154.         mov eax,dword[data_rgba]
  2155.  
  2156.         mov eax,dword[data_rgba]
  2157.         mov ebx,eax
  2158.         add ebx,4
  2159.         mov ecx,dword[size] ;ecx = size
  2160.         shr ecx,1
  2161.         @@: ;смешивание цветов пикселей
  2162.                 call combine_colors_1
  2163.                 mov [eax],edx
  2164.                 add eax,8 ;=2*4
  2165.                 add ebx,8
  2166.                 loop @b
  2167.  
  2168.         mov eax,dword[data_rgba]
  2169.         add eax,4
  2170.         mov ebx,eax
  2171.         add ebx,4
  2172.         mov ecx,dword[size] ;ecx = size
  2173.         shr ecx,1
  2174.         dec ecx ;лишний пиксель
  2175.         @@: ;поджатие пикселей
  2176.                 mov edx,dword[ebx]
  2177.                 mov dword[eax],edx
  2178.  
  2179.                 add eax,4
  2180.                 add ebx,8
  2181.                 loop @b
  2182.         ret
  2183. endp
  2184.  
  2185. ;description:
  2186. ; сжатие изображения по высоте (высота буфера не меняется)
  2187. align 4
  2188. proc buf_img_hdiv2, buf_struc:dword
  2189.         pushad
  2190.         mov edi,dword[buf_struc]
  2191.         cmp buf2d_bits,8
  2192.         jne @f
  2193.                 mov eax,buf2d_w
  2194.                 mov ecx,buf2d_h
  2195.                 imul ecx,eax
  2196.                 stdcall img_8b_hdiv2, buf2d_data,ecx,eax
  2197.                 jmp .end_f ;edi портится в функции, потому использование buf2d_bits опасно
  2198.         @@:
  2199.         cmp buf2d_bits,24
  2200.         jne @f
  2201.                 mov eax,buf2d_w
  2202.                 mov ecx,buf2d_h
  2203.                 imul ecx,eax
  2204.                 stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
  2205.                 jmp .end_f
  2206.         @@:
  2207.         cmp buf2d_bits,32
  2208.         jne @f
  2209.                 mov eax,buf2d_w
  2210.                 mov ecx,buf2d_h
  2211.                 imul ecx,eax
  2212.                 shl eax,2
  2213.                 stdcall img_rgba32_hdiv2, buf2d_data,ecx,eax
  2214.                 ;jmp .end_f
  2215.         @@:
  2216.         .end_f:
  2217.         popad
  2218.         ret
  2219. endp
  2220.  
  2221. ;input:
  2222. ;data_8b - pointer to 8 bit data
  2223. ;size - count img pixels (size img data)
  2224. ;size_w - width img in pixels
  2225. align 4
  2226. proc img_8b_hdiv2, data_8b:dword, size:dword, size_w:dword
  2227.  
  2228.         mov eax,dword[data_8b] ;eax =
  2229.         mov ecx,dword[size]
  2230.         cld
  2231.         @@: ;затемнение цвета пикселей
  2232.                 shr byte[eax],1
  2233.                 inc eax
  2234.                 loop @b
  2235.  
  2236.         mov eax,dword[data_8b] ;eax =
  2237.         mov esi,dword[size_w]
  2238.         mov ebx,esi
  2239.         add ebx,eax
  2240.         mov ecx,dword[size]  ;ecx = size
  2241.         shr ecx,1
  2242.         xor edi,edi
  2243.         @@: ;сложение цветов пикселей
  2244.                 mov dl,byte[ebx] ;копируем цвет нижнего пикселя
  2245.                 add byte[eax],dl
  2246.  
  2247.                 inc eax
  2248.                 inc ebx
  2249.                 inc edi
  2250.                 cmp edi,dword[size_w]
  2251.                 jl .old_line
  2252.                         add eax,esi
  2253.                         add ebx,esi
  2254.                         xor edi,edi
  2255.                 .old_line:
  2256.                 loop @b
  2257.  
  2258.  
  2259.         mov eax,dword[data_8b] ;eax =
  2260.         add eax,esi ;esi = width*3(rgb)
  2261.         mov ebx,eax
  2262.         add ebx,esi
  2263.         mov ecx,dword[size] ;ecx = size
  2264.         shr ecx,1
  2265.         sub ecx,dword[size_w] ;лишняя строка пикселей
  2266.         xor edi,edi
  2267.         @@: ;поджатие пикселей
  2268.                 mov dl,byte[ebx] ;копируем цвет нижнего пикселя
  2269.                 mov byte[eax],dl
  2270.  
  2271.                 inc eax
  2272.                 inc ebx
  2273.                 inc edi
  2274.                 cmp edi,dword[size_w]
  2275.                 jl .old_line_2
  2276.                         add ebx,esi
  2277.                         xor edi,edi
  2278.                 .old_line_2:
  2279.                 loop @b
  2280.  
  2281.         ret
  2282. endp
  2283.  
  2284. ;input:
  2285. ;data_rgb - pointer to rgb data
  2286. ;size - count img pixels (size img data / 3(rgb) )
  2287. ;size_w - width img in pixels
  2288. align 4
  2289. proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword
  2290.  
  2291.   mov eax,dword[data_rgb] ;eax =
  2292.   mov ecx,dword[size]     ;ecx = size
  2293.   lea ecx,[ecx+ecx*2]
  2294.   cld
  2295.   @@: ;затемнение цвета пикселей
  2296.     shr byte[eax],1
  2297.     inc eax
  2298.     loop @b
  2299.  
  2300.   mov eax,dword[data_rgb] ;eax =
  2301.   mov esi,dword[size_w]
  2302.   lea esi,[esi+esi*2] ;esi = width*3(rgb)
  2303.   mov ebx,esi
  2304.   add ebx,eax
  2305.   mov ecx,dword[size]  ;ecx = size
  2306.   shr ecx,1
  2307.   xor edi,edi
  2308.   @@: ;сложение цветов пикселей
  2309.     mov dx,word[ebx] ;копируем цвет нижнего пикселя
  2310.     add word[eax],dx
  2311.     mov dl,byte[ebx+2] ;копируем цвет нижнего пикселя
  2312.     add byte[eax+2],dl
  2313.  
  2314.     add eax,3
  2315.     add ebx,3
  2316.     inc edi
  2317.     cmp edi,dword[size_w]
  2318.     jl .old_line
  2319.       add eax,esi
  2320.       add ebx,esi
  2321.       xor edi,edi
  2322.     .old_line:
  2323.     loop @b
  2324.  
  2325.  
  2326.   mov eax,dword[data_rgb] ;eax =
  2327.   add eax,esi ;esi = width*3(rgb)
  2328.   mov ebx,eax
  2329.   add ebx,esi
  2330.   mov ecx,dword[size] ;ecx = size
  2331.   shr ecx,1
  2332.   sub ecx,dword[size_w] ;лишняя строка пикселей
  2333.   xor edi,edi
  2334.   @@: ;поджатие пикселей
  2335.     mov edx,dword[ebx] ;копируем цвет нижнего пикселя
  2336.     mov word[eax],dx
  2337.     shr edx,16
  2338.     mov byte[eax+2],dl
  2339.  
  2340.     add eax,3
  2341.     add ebx,3
  2342.     inc edi
  2343.     cmp edi,dword[size_w]
  2344.     jl .old_line_2
  2345.       add ebx,esi
  2346.       xor edi,edi
  2347.     .old_line_2:
  2348.     loop @b
  2349.  
  2350.   ret
  2351. endp
  2352.  
  2353. ;input:
  2354. ;data_rgba - pointer to rgba data
  2355. ;size - count img pixels (size img data / 4(rgba) )
  2356. ;size_w_b - width img in bytes
  2357. align 4
  2358. proc img_rgba32_hdiv2, data_rgba:dword, size:dword, size_w_b:dword
  2359.  
  2360.         mov eax,dword[data_rgba] ;eax =
  2361.         mov ebx,dword[size_w_b]
  2362.         add ebx,eax
  2363.         mov ecx,dword[size]  ;ecx = size
  2364.         shr ecx,1
  2365.         xor edi,edi
  2366.         @@: ;смешивание цветов пикселей
  2367.                 call combine_colors_1
  2368.                 mov dword[eax],edx
  2369.  
  2370.                 add eax,4
  2371.                 add ebx,4
  2372.                 add edi,4
  2373.                 cmp edi,dword[size_w_b]
  2374.                 jl .old_line
  2375.                         add eax,dword[size_w_b]
  2376.                         add ebx,dword[size_w_b]
  2377.                         xor edi,edi
  2378.                 .old_line:
  2379.                 loop @b
  2380.  
  2381.  
  2382.         mov eax,dword[data_rgba] ;eax =
  2383.         mov ebx,dword[size_w_b]
  2384.         add eax,ebx
  2385.         add ebx,eax
  2386.         mov ecx,dword[size] ;ecx = size
  2387.         shl ecx,1
  2388.         sub ecx,dword[size_w_b] ;лишняя строка пикселей
  2389.         shr ecx,2
  2390.         xor edi,edi
  2391.         @@: ;поджатие пикселей
  2392.                 mov edx,dword[ebx] ;копируем цвет нижнего пикселя
  2393.                 mov dword[eax],edx
  2394.  
  2395.                 add eax,4
  2396.                 add ebx,4
  2397.                 add edi,4
  2398.                 cmp edi,dword[size_w_b]
  2399.                 jl .old_line_2
  2400.                         add ebx,dword[size_w_b]
  2401.                         xor edi,edi
  2402.                 .old_line_2:
  2403.                 loop @b
  2404.  
  2405.         ret
  2406. endp
  2407.  
  2408. ;input:
  2409. ; eax - указатель на 32-битный цвет
  2410. ; ebx - указатель на 32-битный цвет
  2411. ;output:
  2412. ; edx - 32-битный цвет смешанный с учетом прозрачности
  2413. ;destroy:
  2414. ; esi
  2415. align 4
  2416. proc combine_colors_1 uses ecx edi
  2417. locals
  2418.         c_blye dd ?
  2419.         c_green dd ?
  2420.         c_red dd ?
  2421. endl           
  2422.         movzx edi,byte[eax+3]
  2423.         cmp edi,255
  2424.         je .c0z
  2425.         movzx esi,byte[ebx+3]
  2426.         cmp esi,255
  2427.         je .c1z
  2428.         cmp edi,esi
  2429.         je .c0_c1
  2430.  
  2431.         ;переворачиваем значения прозрачностей
  2432.         neg edi
  2433.         inc edi
  2434.         add edi,255
  2435.         neg esi
  2436.         inc esi
  2437.         add esi,255
  2438.  
  2439.         movzx ecx,byte[eax]
  2440.         imul ecx,edi
  2441.         mov [c_blye],ecx
  2442.         movzx ecx,byte[ebx]
  2443.         imul ecx,esi
  2444.         add [c_blye],ecx
  2445.  
  2446.         movzx ecx,byte[eax+1]
  2447.         imul ecx,edi
  2448.         mov [c_green],ecx
  2449.         movzx ecx,byte[ebx+1]
  2450.         imul ecx,esi
  2451.         add [c_green],ecx
  2452.  
  2453.         movzx ecx,byte[eax+2]
  2454.         imul ecx,edi
  2455.         mov [c_red],ecx
  2456.         movzx ecx,byte[ebx+2]
  2457.         imul ecx,esi
  2458.         add [c_red],ecx
  2459.  
  2460. push eax ebx
  2461.         xor ebx,ebx
  2462.         mov eax,[c_red]
  2463.         xor edx,edx
  2464.         mov ecx,edi
  2465.         add ecx,esi
  2466.         div ecx
  2467.         mov bl,al
  2468.         shl ebx,16
  2469.         mov eax,[c_green]
  2470.         xor edx,edx
  2471.         div ecx
  2472.         mov bh,al
  2473.         mov eax,[c_blye]
  2474.         xor edx,edx
  2475.         div ecx
  2476.         mov bl,al
  2477.  
  2478.         shr ecx,1
  2479.         ;переворачиваем значения прозрачности
  2480.         neg ecx
  2481.         inc ecx
  2482.         add ecx,255
  2483.  
  2484.         shl ecx,24
  2485.         add ebx,ecx
  2486.         mov edx,ebx
  2487. pop ebx eax
  2488.  
  2489.         jmp .end_f
  2490.         .c0_c1: ;если прозрачности обоих цветов совпадают
  2491.                 mov edx,dword[eax]
  2492.                 shr edx,1
  2493.                 and edx,011111110111111101111111b
  2494.                 mov esi,dword[ebx]
  2495.                 shr esi,1
  2496.                 and esi,011111110111111101111111b
  2497.                 add edx,esi
  2498.                 ror edi,8 ;перемещаем значение прозрачности в старший байт edi
  2499.                 or edx,edi
  2500.                 jmp .end_f
  2501.         .c0z: ;если цвет в eax прозрачный
  2502.                 mov edx,dword[ebx]
  2503.                 movzx edi,byte[ebx+3]
  2504.                 jmp @f
  2505.         .c1z: ;если цвет в ebx прозрачный
  2506.                 mov edx,dword[eax]
  2507.         @@:
  2508.                 add edi,255 ;делаем цвет на половину прозрачным
  2509.                 shr edi,1
  2510.                 cmp edi,255
  2511.                 jl @f
  2512.                         mov edi,255 ;максимальная прозрачность не более 255
  2513.                 @@:
  2514.                 shl edi,24
  2515.                 and edx,0xffffff ;снимаем старую прозрачность
  2516.                 add edx,edi
  2517.         .end_f:
  2518.         ret
  2519. endp
  2520.  
  2521. ;преобразование буфера из 24-битного в 8-битный
  2522. ; spectr - определяет какой спектр брать при преобразовании 0-синий, 1-зеленый, 2-красный
  2523. align 4
  2524. proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
  2525.         pushad
  2526.         mov edi,dword[buf_struc]
  2527.         cmp buf2d_bits,24
  2528.         jne .error
  2529.                 mov eax,buf2d_w
  2530.                 mov ecx,buf2d_h
  2531.                 imul ecx,eax
  2532.                 mov esi,ecx
  2533.                 ;ebx - память из которой копируется
  2534.                 ;edx - память куда копируется
  2535.                 mov edx,buf2d_data
  2536.                 mov ebx,edx
  2537.                 cmp [spectr],3
  2538.                 jge @f
  2539.                         add ebx,[spectr]
  2540.                 @@:
  2541.                         mov al,byte[ebx]
  2542.                         mov byte[edx],al
  2543.                         add ebx,3
  2544.                         inc edx
  2545.                         loop @b
  2546.                 mov buf2d_bits,8
  2547.                 invoke mem.realloc,buf2d_data,esi ;уменьшаем память занимаемую буфером
  2548.                 jmp .end_conv
  2549.         .error:
  2550.                 stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
  2551.         .end_conv:
  2552.         popad
  2553.         ret
  2554. endp
  2555.  
  2556. ;преобразование буфера из 24-битного в 32-битный
  2557. align 4
  2558. proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
  2559.         pushad
  2560.         mov edi,dword[buf_struc]
  2561.         cmp buf2d_bits,24
  2562.         jne .error1
  2563.                 mov ecx,buf2d_w
  2564.                 mov ebx,buf2d_h
  2565.                 imul ebx,ecx
  2566.                 mov ecx,ebx ;ecx = size  8 b
  2567.                 shl ebx,2   ;ebx = size 32 b
  2568.                 invoke mem.realloc,buf2d_data,ebx ;увеличиваем память занимаемую буфером
  2569.                 mov buf2d_data,eax ;на случай если изменился указатель на данные
  2570.                 mov buf2d_bits,32
  2571.                 mov edx,ebx ;edx = size 32 b
  2572.                 sub ebx,ecx ;ebx = size 24 b
  2573.                 mov eax,ecx
  2574.                 ;eax - размер  8 битных данных
  2575.                 ;ebx - размер 24 битных данных
  2576.                 ;edx - размер 32 битных данных
  2577.                 add ebx,buf2d_data
  2578.                 add edx,buf2d_data
  2579.                 mov edi,dword[buf_str8]
  2580.                 cmp buf2d_bits,8