Subversion Repositories Kolibri OS

Rev

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

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