Subversion Repositories Kolibri OS

Rev

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