Subversion Repositories Kolibri OS

Rev

Rev 3053 | 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. ;;================================================================================================;;
  22. proc img.get_scaled_size _width, _height, _scale_type, _param1, _param2                           ;;
  23. ;;------------------------------------------------------------------------------------------------;;
  24. ;? calculate resulting width and height if image of _width and _height is scaled via _scale_type  ;;
  25. ;;------------------------------------------------------------------------------------------------;;
  26. ;> [_width]      = width of input image                                                           ;;
  27. ;> [_height]     = height of input image                                                          ;;
  28. ;> [_scale_type] = see libimg.inc (LIBIMG_SCALE_*)                                                ;;
  29. ;> [_param1]     = depends on _scale_type, see libimg.inc                                         ;;
  30. ;> [_param2]     = depends on _scale_type, see libimg.inc                                         ;;
  31. ;;------------------------------------------------------------------------------------------------;;
  32. ;< eax = width                                                                                    ;;
  33. ;< ecx = height                                                                                   ;;
  34. ;;================================================================================================;;
  35.         push    ebx esi edi
  36.         mov     eax, [_scale_type]
  37.         cmp     eax, LIBIMG_SCALE_FIT_MIN
  38.         jz      .fit_min
  39.  
  40.   .fit_min:
  41.         xor     edx, edx
  42.         mov     eax, [_width]
  43.         shl     eax, 1
  44.         mov     ecx, [_param1]
  45.         add     eax, ecx
  46.         shl     eax, 15
  47.         div     ecx
  48.         mov     ebx, eax
  49.  
  50.         xor     edx, edx
  51.         mov     eax, [_height]
  52.         shl     eax, 1
  53.         mov     ecx, [_param2]
  54.         add     eax, ecx
  55.         shl     eax, 15
  56.         div     ecx
  57.  
  58.         cmp     eax, ebx
  59.         ja      .fit_height
  60.         jmp     .fit_width
  61.  
  62.         jmp     .quit
  63.   .fit_max:
  64.         jmp     .quit
  65.   .fit_width:
  66.         xor     edx, edx
  67.         mov     eax, [_width]
  68.         shl     eax, 16
  69.         div     [_param1]
  70.         mov     ecx, eax
  71.         xor     edx, edx
  72.         mov     eax, [_height]
  73.         shl     eax, 16
  74.         mov     ebx, ecx
  75.         shr     ebx, 1
  76.         add     eax, ebx
  77.         div     ecx
  78.         mov     ecx, eax
  79.         mov     eax, [_param1]
  80.         jmp     .quit
  81.   .fit_height:
  82.         xor     edx, edx
  83.         mov     eax, [_height]
  84.         shl     eax, 16
  85.         div     [_param2]
  86.         mov     ecx, eax
  87.         xor     edx, edx
  88.         mov     eax, [_width]
  89.         shl     eax, 16
  90.         mov     ebx, ecx
  91.         shr     ebx, 1
  92.         add     eax, ebx
  93.         div     ecx
  94.         mov     ecx, [_param2]
  95.         jmp     .quit
  96.  
  97.   .quit:
  98.         pop     edi esi ebx
  99.         ret
  100. endp
  101.  
  102.  
  103. ;;================================================================================================;;
  104. proc img.scale _src, _crop_x, _crop_y, _crop_width, _crop_height, _dst, _scale, _inter, _param1, _param2 ;;
  105. ;;------------------------------------------------------------------------------------------------;;
  106. ;? scale _image                                                                                   ;;
  107. ;;------------------------------------------------------------------------------------------------;;
  108. ;> [_src]         = pointer to source image                                                       ;;
  109. ;> [_crop_x]      = left coord of cropping rect                                                   ;;
  110. ;> [_crop_y]      = top coord of cropping rect                                                    ;;
  111. ;> [_crop_width]  = width of cropping rect                                                        ;;
  112. ;> [_crop_height] = height of cropping rect                                                       ;;
  113. ;> [_dst]         = pointer to resulting image, 0 to create new one                               ;;
  114. ;> [_scale]       = scaling method, see libimg.inc (LIBIMG_SCALE_*)                               ;;
  115. ;> [_inter]       = interpolation algorithm, see libimg.inc (LIBIMG_INTER_*)                      ;;
  116. ;> [_param1]      = depends on _scale, see libimg.inc                                             ;;
  117. ;> [_param2]      = depends on _scale, see libimg.inc                                             ;;
  118. ;;------------------------------------------------------------------------------------------------;;
  119. ;< eax = 0 / pointer to scaled image                                                              ;;
  120. ;< ecx = error code / undefined                                                                   ;;
  121. ;;================================================================================================;;
  122.         push    ebx esi edi 0 0
  123.         mov     ebx, [_src]
  124.     @@:
  125.         mov     eax, [ebx + Image.Previous]
  126.         test    eax, eax
  127.         jz      .loop
  128.         mov     ebx, eax
  129.         jmp     @b
  130.   .loop:
  131.         stdcall img.scale.layer, ebx, [_crop_x], [_crop_y], [_crop_width], [_crop_height], [_dst], [_scale], [_inter], [_param1], [_param2]
  132.         test    eax, eax
  133.         jz      .error
  134.         cmp     dword[esp + 4], 0
  135.         jnz     @f
  136.         mov     [esp + 4], eax
  137.     @@:
  138.         mov     ecx, [esp]
  139.         jecxz   @f
  140.         mov     [ecx + Image.Next], eax
  141.     @@:
  142.         push    [ebx + Image.Flags]
  143.         pop     [eax + Image.Flags]
  144.         push    [ebx + Image.Delay]
  145.         pop     [eax + Image.Delay]
  146.         mov     [eax + Image.Previous], ecx
  147.         mov     [esp], eax
  148.         mov     ebx, [ebx + Image.Next]
  149.         test    ebx, ebx
  150.         jnz     .loop
  151.   .quit:
  152.         pop     eax eax edi esi ebx
  153.         ret
  154.   .error:
  155.         pop     eax eax edi esi ebx
  156.         ret
  157. endp
  158.  
  159.  
  160. ;;================================================================================================;;
  161. proc img.scale.layer _src, _crop_x, _crop_y, _crop_width, _crop_height, _dst, _scale, _inter, _param1, _param2 ;;
  162. ;;------------------------------------------------------------------------------------------------;;
  163. ;? scale _image layer                                                                             ;;
  164. ;;------------------------------------------------------------------------------------------------;;
  165. ;> [_src]         = pointer to source image                                                       ;;
  166. ;> [_crop_x]      = left coord of cropping rect                                                   ;;
  167. ;> [_crop_y]      = top coord of cropping rect                                                    ;;
  168. ;> [_crop_width]  = width of cropping rect                                                        ;;
  169. ;> [_crop_height] = height of cropping rect                                                       ;;
  170. ;> [_dst]         = pointer to resulting image, 0 to create new one                               ;;
  171. ;> [_scale]       = scaling method, see libimg.inc (LIBIMG_SCALE_*)                               ;;
  172. ;> [_inter]       = interpolation algorithm, see libimg.inc (LIBIMG_INTER_*)                      ;;
  173. ;> [_param1]      = depends on _scale, see libimg.inc                                             ;;
  174. ;> [_param2]      = depends on _scale, see libimg.inc                                             ;;
  175. ;;------------------------------------------------------------------------------------------------;;
  176. ;< eax = 0 / pointer to scaled image                                                              ;;
  177. ;< ecx = error code / undefined                                                                   ;;
  178. ;;================================================================================================;;
  179. locals
  180.         src_type                rd 1
  181.         src_data                rd 1
  182.         dst_data                rd 1
  183.  
  184.         src_width_pixels        rd 1
  185.         src_width_bytes         rd 1
  186.         src_height_pixels       rd 1
  187.  
  188.         dst_width_pixels        rd 1
  189.         dst_width_pixels_inv    rd 1
  190.         dst_height_pixels       rd 1
  191.         dst_height_pixels_inv   rd 1
  192.         dst_width_bytes         rd 1
  193.         bytes_per_pixel         rd 1
  194.  
  195.         crop_width_pixels_m1    rd 1
  196.         crop_height_pixels_m1   rd 1
  197. ; bilinear
  198.         src_x           rd 1
  199.         src_y           rd 1
  200.         src_base        rd 1
  201.         dst_x           rd 1
  202.         dst_y           rd 1
  203.         rem_x           rd 1
  204.         rem_y           rd 1
  205. endl
  206.         push    ebx esi edi
  207.         mov     ebx, [_src]
  208.         push    [ebx + Image.Width]
  209.         pop     [src_width_pixels]
  210.         push    [ebx + Image.Height]
  211.         pop     [src_height_pixels]
  212.         push    [ebx + Image.Type]
  213.         pop     [src_type]
  214.         push    [ebx + Image.Data]
  215.         pop     [src_data]
  216.  
  217.         mov     eax, [src_type]
  218.         mov     ecx, [src_width_pixels]
  219.         mov     edx, [src_width_pixels]
  220.         imul    edx, [_crop_y]
  221.         add     edx, [_crop_x]
  222.         cmp     eax, Image.bpp32
  223.         jne     @f
  224.         mov     [bytes_per_pixel], 4
  225.         shl     ecx, 2
  226.         shl     edx, 2
  227.         jmp     .lab1
  228.     @@:
  229.         cmp     eax, Image.bpp24
  230.         jne     @f
  231.         mov     [bytes_per_pixel], 3
  232.         lea     ecx, [ecx*3]
  233.         lea     edx, [edx*3]
  234.         jmp     .lab1
  235.     @@:
  236.         cmp     eax, Image.bpp8g
  237.         jne     @f
  238.         mov     [bytes_per_pixel], 1
  239.         jmp     .lab1
  240.     @@:
  241.         mov     ecx, LIBIMG_ERROR_BIT_DEPTH
  242.         jmp     .error
  243.   .lab1:
  244.         mov     [src_width_bytes], ecx
  245.         add     [src_data], edx
  246.  
  247.  
  248.         mov     eax, [_scale]
  249.         cmp     eax, LIBIMG_SCALE_INTEGER
  250.         je      .scale_type.integer
  251.         cmp     eax, LIBIMG_SCALE_TILE
  252.         je      .scale_type.tile
  253.         cmp     eax, LIBIMG_SCALE_FIT_RECT
  254.         je      .scale_type.fit_rect
  255.         cmp     eax, LIBIMG_SCALE_FIT_WIDTH
  256.         je      .scale_type.fit_width
  257.         cmp     eax, LIBIMG_SCALE_FIT_HEIGHT
  258.         je      .scale_type.fit_height
  259.         cmp     eax, LIBIMG_SCALE_FIT_MAX
  260.         je      .scale_type.fit_max
  261.         cmp     eax, LIBIMG_SCALE_STRETCH
  262.         je      .scale_type.stretch
  263.         mov     ecx, LIBIMG_ERROR_SCALE
  264.         jmp     .error
  265.  
  266.   .scale_type.integer:
  267.         jmp     .integer
  268.   .scale_type.tile:
  269.         jmp     .tile
  270.   .scale_type.fit_rect:
  271.   .scale_type.fit_max:
  272.   .scale_type.fit_width:
  273.   .scale_type.fit_height:
  274.         mov     eax, [_src]
  275.         stdcall img.get_scaled_size, [eax + Image.Width], [eax + Image.Height], [_scale], [_param1], [_param2]
  276.         mov     [_param1], eax
  277.         mov     [_param2], ecx
  278.   .scale_type.stretch:
  279.         mov     eax, [_param1]
  280.         mov     [dst_width_pixels], eax
  281.         imul    eax, [bytes_per_pixel]
  282.         mov     [dst_width_bytes], eax
  283.         mov     ecx, [_param2]
  284.         mov     [dst_height_pixels], ecx
  285.         jmp     .define_inter
  286.   .define_inter:
  287.         mov     eax, [_inter]
  288.         cmp     eax, LIBIMG_INTER_BILINEAR
  289.         je      .bilinear
  290.         mov     ecx, LIBIMG_ERROR_INTER
  291.         jmp     .error
  292.  
  293.  
  294.   .integer:
  295.         mov     eax, [_param1]
  296.         mov     ecx, [_crop_width]
  297.         imul    ecx, eax
  298.         mov     [dst_width_pixels], ecx
  299.         mov     edx, [_crop_height]
  300.         imul    edx, eax
  301.         mov     [dst_height_pixels], edx
  302.  
  303.         mov     eax, [_dst]
  304.         test    eax, eax
  305.         jnz     @f
  306.         stdcall img.create, [dst_width_pixels], [dst_height_pixels], [src_type]
  307.         test    eax, eax
  308.         jz      .error
  309.         mov     [_dst], eax
  310.         mov     edi, [_src]
  311.         push    [edi + Image.Flags]
  312.         pop     [eax + Image.Flags]
  313.         push    [edi + Image.Delay]
  314.         pop     [eax + Image.Delay]
  315.         push    [edi + Image.Previous]
  316.         pop     [eax + Image.Previous]
  317.         push    [edi + Image.Next]
  318.         pop     [eax + Image.Next]
  319.     @@:
  320.         mov     edi, [eax + Image.Data]
  321.         mov     [dst_data], edi
  322.  
  323.         mov     esi, [src_data]
  324.         mov     eax, [src_type]
  325.         cmp     eax, Image.bpp8g
  326.         je      .integer.bpp8g
  327.         cmp     eax, Image.bpp24
  328.         je      .integer.bpp24
  329.         cmp     eax, Image.bpp32
  330.         je      .integer.bpp32
  331.         mov     ecx, LIBIMG_ERROR_BIT_DEPTH
  332.         jmp     .error
  333.  
  334.   .integer.bpp8g:
  335.         push    [dst_width_pixels]
  336.         pop [dst_width_bytes]
  337.         mov ecx, [_param1]
  338. ;   cmp ecx, 1
  339. ;   je  .error
  340.   .integer.bpp8g.common:
  341.         mov edx, ecx
  342.         mov ebx, [_crop_height]
  343.   .integer.bpp8g.common.line:
  344.         push    ebx
  345.         mov ebx, [_crop_width]
  346.         @@:
  347.         lodsb
  348.         mov ecx, edx
  349.         rep stosb
  350.         dec ebx
  351.         jnz @b
  352.         push    esi
  353.         mov esi, edi
  354.         sub esi, [dst_width_bytes]
  355.         mov ecx, edx
  356.         dec ecx
  357.         imul    ecx, [dst_width_bytes]
  358.         mov eax, ecx
  359.         shr ecx, 2
  360.         and eax, 0x00000003
  361.         rep movsd
  362.         mov ecx, eax
  363.         rep movsb
  364.         pop esi
  365.         mov eax, [src_width_pixels]
  366.         sub eax, [_crop_width]
  367.         add esi, eax
  368.         pop ebx
  369.         dec ebx
  370.         jnz .integer.bpp8g.common.line
  371.         mov eax, [_dst]
  372.         jmp .quit
  373.  
  374.   .integer.bpp24:
  375.         mov eax, [dst_width_pixels]
  376.         lea eax, [eax*3]
  377.         mov [dst_width_bytes], eax
  378.         mov ecx, [_param1]
  379. ;   cmp ecx, 1
  380. ;   je  .error
  381.   .integer.bpp24.common:
  382.         mov edx, ecx
  383.         mov ebx, [_crop_height]
  384.   .integer.bpp24.common.line:
  385.         push    ebx
  386.         mov ebx, [_crop_width]
  387.         @@:
  388.         movsw
  389.         movsb
  390.         mov ecx, edx
  391.         push    esi
  392.         mov esi, edi
  393.         sub esi, 3
  394.         dec ecx
  395.         lea ecx, [ecx*3]
  396.         rep movsb
  397.         pop esi
  398.         dec ebx
  399.         jnz @b
  400.         push    esi
  401.         mov esi, edi
  402.         sub esi, [dst_width_bytes]
  403.         mov ecx, edx
  404.         dec ecx
  405.         imul    ecx, [dst_width_bytes]
  406.         mov eax, ecx
  407.         shr ecx, 2
  408.         and eax, 0x00000003
  409.         rep movsd
  410.         mov ecx, eax
  411.         rep movsb
  412.         pop esi
  413.         mov eax, [src_width_pixels]
  414.         sub eax, [_crop_width]
  415.         lea eax, [eax*3]
  416.         add esi, eax
  417.         pop ebx
  418.         dec ebx
  419.         jnz .integer.bpp24.common.line
  420.         mov eax, [_dst]
  421.         jmp .quit
  422.  
  423.   .integer.bpp32:
  424.         mov eax, [dst_width_pixels]
  425.         shl eax, 2
  426.         mov [dst_width_bytes], eax
  427.         mov ecx, [_param1]
  428. ;   cmp ecx, 1
  429. ;   je  .error
  430.   .integer.bpp32.common:
  431.         mov edx, ecx
  432.         mov ebx, [_crop_height]
  433.   .integer.bpp32.common.line:
  434.         push    ebx
  435.         mov ebx, [_crop_width]
  436.         @@:
  437.         lodsd
  438.         mov ecx, edx
  439.         rep stosd
  440.         dec ebx
  441.         jnz @b
  442.         push    esi
  443.         mov esi, edi
  444.         sub esi, [dst_width_bytes]
  445.         mov ecx, edx
  446.         dec ecx
  447.         imul    ecx, [dst_width_bytes]
  448.         shr ecx, 2
  449.         rep movsd
  450.         pop esi
  451.         mov eax, [src_width_pixels]
  452.         sub eax, [_crop_width]
  453.         shl eax, 2
  454.         add esi, eax
  455.         pop ebx
  456.         dec ebx
  457.         jnz .integer.bpp32.common.line
  458.         mov eax, [_dst]
  459.         jmp .quit
  460.  
  461.  
  462.   .tile:
  463.         mov eax, [_param1]
  464.         mov [dst_width_pixels], eax
  465.         imul    eax, [bytes_per_pixel]
  466.         mov [dst_width_bytes], eax
  467.         mov eax, [_param2]
  468.         mov [dst_height_pixels], eax
  469.  
  470.         mov eax, [_dst]
  471.         test    eax, eax
  472.         jnz @f
  473.         stdcall img.create, [dst_width_pixels], [dst_height_pixels], [src_type]
  474.         test    eax, eax
  475.         jz  .error
  476.         mov [_dst], eax
  477.         mov     edi, [_src]
  478.         push    [edi + Image.Flags]
  479.         pop     [eax + Image.Flags]
  480.         push    [edi + Image.Delay]
  481.         pop     [eax + Image.Delay]
  482.         push    [edi + Image.Previous]
  483.         pop     [eax + Image.Previous]
  484.         push    [edi + Image.Next]
  485.         pop     [eax + Image.Next]
  486.         @@:
  487.         mov edi, [eax + Image.Data]
  488.         mov [dst_data], edi
  489.  
  490.         mov esi, [src_data]
  491.         mov eax, [_crop_height]
  492.         cmp eax, [dst_height_pixels]
  493.         jna @f
  494.         mov eax, [dst_height_pixels]
  495.         @@:
  496.         push    eax
  497.         mov ecx, [_crop_width]
  498.         cmp ecx, [dst_width_pixels]
  499.         jna @f
  500.         mov ecx, [dst_width_pixels]
  501.         @@:
  502.         imul    ecx, [bytes_per_pixel]
  503.         mov edx, ecx
  504.         @@:
  505.         mov ecx, edx
  506.         rep movsb
  507.  
  508.         push    esi
  509.         mov esi, edi
  510.         sub esi, edx
  511.         mov ecx, [dst_width_bytes]
  512.         sub ecx, edx
  513.         rep movsb
  514.         pop esi
  515.  
  516.         mov ecx, [src_width_bytes]
  517.         sub ecx, edx
  518.         add esi, ecx
  519.         dec eax
  520.         jnz @b
  521.  
  522.         pop eax
  523.         mov esi, [dst_data]
  524.         mov ecx, [dst_height_pixels]
  525.         sub ecx, eax
  526.         imul    ecx, [dst_width_bytes]
  527.         rep movsb
  528.  
  529.         mov eax, [_dst]
  530.         jmp .quit
  531.  
  532.  
  533.   .bilinear:
  534.         mov eax, [_dst]
  535.         test    eax, eax
  536.         jnz @f
  537.         stdcall img.create, [dst_width_pixels], [dst_height_pixels], [src_type]
  538.         test    eax, eax
  539.         jz  .error
  540.         mov [_dst], eax
  541.         mov     edi, [_src]
  542.         push    [edi + Image.Flags]
  543.         pop     [eax + Image.Flags]
  544.         push    [edi + Image.Delay]
  545.         pop     [eax + Image.Delay]
  546.         push    [edi + Image.Previous]
  547.         pop     [eax + Image.Previous]
  548.         push    [edi + Image.Next]
  549.         pop     [eax + Image.Next]
  550.     @@:
  551.         mov edi, [eax + Image.Data]
  552.         mov [dst_data], edi
  553.  
  554.         push    [_crop_width]
  555.         pop [crop_width_pixels_m1]
  556.         sub [crop_width_pixels_m1], 1
  557.         push    [_crop_height]
  558.         pop [crop_height_pixels_m1]
  559.         sub [crop_height_pixels_m1], 1
  560.  
  561.         mov eax, 0xffffffff
  562.         xor edx, edx
  563.         div [dst_width_pixels]
  564.         mov [dst_width_pixels_inv], eax
  565.         mov eax, 0xffffffff
  566.         xor edx, edx
  567.         div [dst_height_pixels]
  568.         mov [dst_height_pixels_inv], eax
  569.  
  570.         mov eax, [src_type]
  571.         cmp eax, Image.bpp8g
  572.         je  .bilinear.bpp8g
  573.         cmp eax, Image.bpp24
  574.         je  .bilinear.bpp24
  575.         cmp eax, Image.bpp32
  576.         je  .bilinear.bpp32
  577.         mov ecx, LIBIMG_ERROR_BIT_DEPTH
  578.         jmp .error
  579.  
  580.   .bilinear.bpp8g:
  581.         mov esi, [src_data]
  582.         mov [dst_y], 0
  583.         mov eax, 0  ; mov eax, [dst_y]
  584.   .bilinear.bpp8g.line:
  585.         mov esi, [src_data]
  586.         mov [dst_x], 0
  587.         imul    eax, [crop_height_pixels_m1]
  588.         xor edx, edx
  589.         div [dst_height_pixels]
  590.         mov [rem_y], edx
  591.         imul    eax, [src_width_bytes]
  592.         add esi, eax
  593.         mov [src_base], esi
  594.         mov eax, 0  ; mov eax, [dst_x]
  595.  
  596.   .bilinear.bpp8g.pixel:
  597.         mov esi, [src_base]
  598.  
  599.         imul    eax, [crop_width_pixels_m1]
  600.         xor edx, edx
  601.         div [dst_width_pixels]
  602.         add esi, eax
  603.  
  604.         mov ax, word[esi]
  605.         add esi, [src_width_pixels]
  606.         mov bx, word[esi]
  607.         mov esi, edx
  608.         movzx   edx, ah
  609.         and eax, 0x000000ff
  610.         movzx   ecx, bh
  611.         and ebx, 0x000000ff
  612.  
  613.         imul    edx, esi
  614.         imul    ecx, esi
  615.         neg esi
  616.         add esi, [dst_width_pixels]
  617.         imul    eax, esi
  618.         imul    ebx, esi
  619.         add eax, edx
  620.         add ebx, ecx
  621.         mov esi, [dst_width_pixels_inv]
  622.         mul esi
  623.         mov ecx, edx
  624.         mov eax, ebx
  625.         mul esi
  626.         mov eax, edx
  627.  
  628.         mov edx, [rem_y]
  629.         imul    eax, edx
  630.         neg edx
  631.         add edx, [dst_height_pixels]
  632.         imul    ecx, edx
  633.         add eax, ecx
  634.         mul [dst_height_pixels_inv]
  635.         mov byte[edi], dl
  636.         add edi, 1
  637.  
  638.         add [dst_x], 1
  639.         mov eax, [dst_x]
  640.         cmp eax, [dst_width_pixels]
  641.         jne .bilinear.bpp8g.pixel
  642.  
  643.         add [dst_y], 1
  644.         mov eax, [dst_y]
  645.         cmp eax, [dst_height_pixels]
  646.         jne .bilinear.bpp8g.line
  647.  
  648.         mov eax, [_dst]
  649.         jmp .quit
  650.  
  651.  
  652.   .bilinear.bpp24:
  653.         mov esi, [src_data]
  654.         mov [dst_y], 0
  655.         mov eax, 0  ; mov eax, [dst_y]
  656.   .bilinear.bpp24.line:
  657.         mov esi, [src_data]
  658.         mov [dst_x], 0
  659.         imul    eax, [crop_height_pixels_m1]
  660.         xor edx, edx
  661.         div [dst_height_pixels]
  662.         mov [rem_y], edx
  663.         imul    eax, [src_width_bytes]
  664.         add esi, eax
  665.         mov [src_base], esi
  666.         mov eax, 0  ; mov eax, [dst_x]
  667.  
  668.   .bilinear.bpp24.pixel:
  669.         mov esi, [src_base]
  670.  
  671.         imul    eax, [crop_width_pixels_m1]
  672.         xor edx, edx
  673.         div [dst_width_pixels]
  674.         lea eax, [eax*3]
  675.         add esi, eax
  676.  
  677.         mov [rem_x], edx
  678.         sub esi, 1
  679.         mov [src_x], esi
  680.  
  681. repeat 3
  682.         mov edx, [rem_x]
  683.         add [src_x], 1
  684.         mov esi, [src_x]
  685.  
  686.         mov al, byte[esi]
  687.         mov ah, byte[esi + 3]
  688.         add esi, [src_width_bytes]
  689.         movzx   ebx, byte[esi]
  690.         movzx   ecx, byte[esi + 3]
  691.         mov esi, edx
  692.         movzx   edx, ah
  693.         and eax, 0x000000ff
  694.  
  695.         imul    edx, esi
  696.         imul    ecx, esi
  697.         neg esi
  698.         add esi, [dst_width_pixels]
  699.         imul    eax, esi
  700.         imul    ebx, esi
  701.         add eax, edx
  702.         add ebx, ecx
  703.         mov esi, [dst_width_pixels_inv]
  704.         mul esi
  705.         mov ecx, edx
  706.         mov eax, ebx
  707.         mul esi
  708.         mov eax, edx
  709.  
  710.         mov edx, [rem_y]
  711.         imul    eax, edx
  712.         neg edx
  713.         add edx, [dst_height_pixels]
  714.         imul    ecx, edx
  715.         add eax, ecx
  716.         mul [dst_height_pixels_inv]
  717.         mov byte[edi], dl
  718.         add edi, 1
  719. end repeat
  720.  
  721.         add [dst_x], 1
  722.         mov eax, [dst_x]
  723.         cmp eax, [dst_width_pixels]
  724.         jne .bilinear.bpp24.pixel
  725.  
  726.         add [dst_y], 1
  727.         mov eax, [dst_y]
  728.         cmp eax, [dst_height_pixels]
  729.         jne .bilinear.bpp24.line
  730.  
  731.         mov eax, [_dst]
  732.         jmp .quit
  733.  
  734.   .bilinear.bpp32:
  735.         mov esi, [src_data]
  736.         mov [dst_y], 0
  737.         mov eax, 0  ; mov eax, [dst_y]
  738.   .bilinear.bpp32.line:
  739.         mov esi, [src_data]
  740.         mov [dst_x], 0
  741.         imul    eax, [crop_height_pixels_m1]
  742.         xor edx, edx
  743.         div [dst_height_pixels]
  744.         mov [rem_y], edx
  745.         imul    eax, [src_width_bytes]
  746.         add esi, eax
  747.         mov [src_base], esi
  748.         mov eax, 0  ; mov eax, [dst_x]
  749.  
  750.   .bilinear.bpp32.pixel:
  751.         mov esi, [src_base]
  752.  
  753.         imul    eax, [crop_width_pixels_m1]
  754.         xor edx, edx
  755.         div [dst_width_pixels]
  756.         shl eax, 2
  757.         add esi, eax
  758.  
  759.         mov [rem_x], edx
  760.         sub esi, 1
  761.         mov [src_x], esi
  762.  
  763. repeat 4
  764.         mov edx, [rem_x]
  765.         add [src_x], 1
  766.         mov esi, [src_x]
  767.  
  768.         mov al, byte[esi]
  769.         mov ah, byte[esi + 4]
  770.         add esi, [src_width_bytes]
  771.         movzx   ebx, byte[esi]
  772.         movzx   ecx, byte[esi + 4]
  773.         mov esi, edx
  774.         movzx   edx, ah
  775.         and eax, 0x000000ff
  776.  
  777.         imul    edx, esi
  778.         imul    ecx, esi
  779.         neg esi
  780.         add esi, [dst_width_pixels]
  781.         imul    eax, esi
  782.         imul    ebx, esi
  783.         add eax, edx
  784.         add ebx, ecx
  785.         mov esi, [dst_width_pixels_inv]
  786.         mul esi
  787.         mov ecx, edx
  788.         mov eax, ebx
  789.         mul esi
  790.         mov eax, edx
  791.  
  792.         mov edx, [rem_y]
  793.         imul    eax, edx
  794.         neg edx
  795.         add edx, [dst_height_pixels]
  796.         imul    ecx, edx
  797.         add eax, ecx
  798.         mul [dst_height_pixels_inv]
  799.         mov byte[edi], dl
  800.         add edi, 1
  801. end repeat
  802.  
  803.         add [dst_x], 1
  804.         mov eax, [dst_x]
  805.         cmp eax, [dst_width_pixels]
  806.         jne .bilinear.bpp32.pixel
  807.  
  808.         add [dst_y], 1
  809.         mov eax, [dst_y]
  810.         cmp eax, [dst_height_pixels]
  811.         jne .bilinear.bpp32.line
  812.  
  813.         mov eax, [_dst]
  814.         jmp .quit
  815.  
  816.  
  817.   .error:
  818.             xor     eax, eax
  819.   .quit:
  820.             pop     edi esi ebx
  821.             ret
  822. endp
  823.  
  824.