Subversion Repositories Kolibri OS

Rev

Rev 3053 | 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_type, _scale_alg, _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_type]  = how to change width and height. see libimg.inc                                ;;
  32. ;> [_scale_alg]   = algorithm to use. see libimg.inc                                              ;;
  33. ;> [_param1]      = the first argument passed to _scale_alg algorithm                             ;;
  34. ;> [_param2]      = the second argument passed to _scale_alg algorithm                            ;;
  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.         scl_width_pixels        rd 1
  49.         scl_width_pixels_inv    rd 1
  50.         scl_height_pixels       rd 1
  51.         scl_height_pixels_inv   rd 1
  52.         scl_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, [ecx*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_alg]
  108.         cmp     eax, LIBIMG_SCALE_ALG_INTEGER
  109.         je      .integer
  110.         cmp     eax, LIBIMG_SCALE_ALG_BILINEAR
  111.         je      .bilinear
  112.         mov     ecx, LIBIMG_ERROR_SCALE_ALG
  113.         jmp     .error
  114.  
  115.   .integer:
  116.         mov     eax, [_param1]
  117.         mov     ecx, [_crop_width]
  118.         imul    ecx, eax
  119.         mov     [scl_width_pixels], ecx
  120.         mov     edx, [_crop_height]
  121.         imul    edx, eax
  122.         mov     [scl_height_pixels], edx
  123.  
  124.         mov     eax, [_dst]
  125.         test    eax, eax
  126.         jnz     @f
  127.         stdcall img.create, [scl_width_pixels], [scl_height_pixels], [src_type]
  128.         test    eax, eax
  129.         jz      .error
  130.         mov     [_dst], eax
  131.     @@:
  132.         mov     edi, [eax + Image.Data]
  133.         mov     [dst_data], edi
  134.  
  135.         mov     esi, [src_data]
  136.         mov     eax, [src_type]
  137.         cmp     eax, Image.bpp8g
  138.         je      .integer.bpp8g
  139.         cmp     eax, Image.bpp24
  140.         je      .integer.bpp24
  141.         cmp     eax, Image.bpp32
  142.         je      .integer.bpp32
  143.         mov     ecx, LIBIMG_ERROR_BIT_DEPTH
  144.         jmp     .error
  145.  
  146.   .integer.bpp8g:
  147.         push    [scl_width_pixels]
  148.         pop     [scl_width_bytes]
  149.         mov     ecx, [_param1]
  150. ;       cmp     ecx, 1
  151. ;       je      .error
  152.   .integer.bpp8g.common:
  153.         mov     edx, ecx
  154.         mov     ebx, [_crop_height]
  155.   .integer.bpp8g.common.line:
  156.         push    ebx
  157.         mov     ebx, [_crop_width]
  158.     @@:
  159.         lodsb
  160.         mov     ecx, edx
  161.         rep     stosb
  162.         dec     ebx
  163.         jnz     @b
  164.         push    esi
  165.         mov     esi, edi
  166.         sub     esi, [scl_width_bytes]
  167.         mov     ecx, edx
  168.         dec     ecx
  169.         imul    ecx, [scl_width_bytes]
  170.         mov     eax, ecx
  171.         shr     ecx, 2
  172.         and     eax, 0x00000003
  173.         rep     movsd
  174.         mov     ecx, eax
  175.         rep     movsb
  176.         pop     esi
  177.         mov     eax, [src_width_pixels]
  178.         sub     eax, [_crop_width]
  179.         add     esi, eax
  180.         pop     ebx
  181.         dec     ebx
  182.         jnz     .integer.bpp8g.common.line
  183.         mov     eax, [_dst]
  184.         jmp     .quit
  185.  
  186.   .integer.bpp24:
  187.         mov     eax, [scl_width_pixels]
  188.         lea     eax, [eax*3]
  189.         mov     [scl_width_bytes], eax
  190.         mov     ecx, [_param1]
  191. ;       cmp     ecx, 1
  192. ;       je      .error
  193.   .integer.bpp24.common:
  194.         mov     edx, ecx
  195.         mov     ebx, [_crop_height]
  196.   .integer.bpp24.common.line:
  197.         push    ebx
  198.         mov     ebx, [_crop_width]
  199.     @@:
  200.         movsw
  201.         movsb
  202.         mov     ecx, edx
  203.         push    esi
  204.         mov     esi, edi
  205.         sub     esi, 3
  206.         dec     ecx
  207.         lea     ecx, [ecx*3]
  208.         rep     movsb
  209.         pop     esi
  210.         dec     ebx
  211.         jnz     @b
  212.         push    esi
  213.         mov     esi, edi
  214.         sub     esi, [scl_width_bytes]
  215.         mov     ecx, edx
  216.         dec     ecx
  217.         imul    ecx, [scl_width_bytes]
  218.         mov     eax, ecx
  219.         shr     ecx, 2
  220.         and     eax, 0x00000003
  221.         rep     movsd
  222.         mov     ecx, eax
  223.         rep     movsb
  224.         pop     esi
  225.         mov     eax, [src_width_pixels]
  226.         sub     eax, [_crop_width]
  227.         lea     eax, [eax*3]
  228.         add     esi, eax
  229.         pop     ebx
  230.         dec     ebx
  231.         jnz     .integer.bpp24.common.line
  232.         mov     eax, [_dst]
  233.         jmp     .quit
  234.  
  235.   .integer.bpp32:
  236.         mov     eax, [scl_width_pixels]
  237.         shl     eax, 2
  238.         mov     [scl_width_bytes], eax
  239.         mov     ecx, [_param1]
  240. ;       cmp     ecx, 1
  241. ;       je      .error
  242.   .integer.bpp32.common:
  243.         mov     edx, ecx
  244.         mov     ebx, [_crop_height]
  245.   .integer.bpp32.common.line:
  246.         push    ebx
  247.         mov     ebx, [_crop_width]
  248.     @@:
  249.         lodsd
  250.         mov     ecx, edx
  251.         rep     stosd
  252.         dec     ebx
  253.         jnz     @b
  254.         push    esi
  255.         mov     esi, edi
  256.         sub     esi, [scl_width_bytes]
  257.         mov     ecx, edx
  258.         dec     ecx
  259.         imul    ecx, [scl_width_bytes]
  260.         shr     ecx, 2
  261.         rep     movsd
  262.         pop     esi
  263.         mov     eax, [src_width_pixels]
  264.         sub     eax, [_crop_width]
  265.         shl     eax, 2
  266.         add     esi, eax
  267.         pop     ebx
  268.         dec     ebx
  269.         jnz     .integer.bpp32.common.line
  270.         mov     eax, [_dst]
  271.         jmp     .quit
  272.  
  273.  
  274.   .bilinear:
  275.         mov     eax, [_scale_type]
  276.         cmp     eax, LIBIMG_SCALE_TYPE_FIT_RECT
  277.         je      .bilinear.fit_rect
  278.         cmp     eax, LIBIMG_SCALE_TYPE_FIT_WIDTH
  279.         je      .bilinear.fit_width
  280.         cmp     eax, LIBIMG_SCALE_TYPE_FIT_HEIGHT
  281.         je      .bilinear.fit_height
  282.         cmp     eax, LIBIMG_SCALE_TYPE_FIT_MAX
  283.         je      .bilinear.fit_max
  284.         cmp     eax, LIBIMG_SCALE_TYPE_STRETCH
  285.         je      .bilinear.stretch
  286.         mov     ecx, LIBIMG_ERROR_SCALE_TYPE
  287.         jmp     .error
  288.   .bilinear.fit_rect:
  289.         mov     eax, [_param1]
  290.         shl     eax, 16
  291.         add     eax, 0x00008000
  292.         xor     edx, edx
  293.         div     [src_width_pixels]
  294.         mov     ebx, eax
  295.         mov     eax, [_param2]
  296.         shl     eax, 16
  297.         add     eax, 0x00008000
  298.         xor     edx, edx
  299.         div     [src_height_pixels]
  300.         mov     ecx, eax
  301.         cmp     ebx, ecx
  302.         jb      @f
  303.         mov     ebx, ecx
  304.     @@:
  305.         jmp     .bilinear.fit_common
  306.   .bilinear.fit_max:
  307.         mov     eax, [_param1]
  308.         shl     eax, 16
  309.         add     eax, 0x00008000
  310.         xor     edx, edx
  311.         div     [src_width_pixels]
  312.         mov     ebx, eax
  313.         mov     eax, [_param2]
  314.         shl     eax, 16
  315.         add     eax, 0x00008000
  316.         xor     edx, edx
  317.         div     [src_height_pixels]
  318.         mov     ecx, eax
  319.         cmp     ebx, ecx
  320.         ja      @f
  321.         mov     ebx, ecx
  322.     @@:
  323.         jmp     .bilinear.fit_common
  324.   .bilinear.fit_width:
  325.         mov     eax, [_param1]
  326.         shl     eax, 16
  327.         add     eax, 0x00008000
  328.         xor     edx, edx
  329.         div     [src_width_pixels]
  330.         mov     ebx, eax
  331.         jmp     .bilinear.fit_common
  332.   .bilinear.fit_height:
  333.         mov     eax, [_param2]
  334.         shl     eax, 16
  335.         add     eax, 0x00008000
  336.         xor     edx, edx
  337.         div     [src_height_pixels]
  338.         mov     ebx, eax
  339.         jmp     .bilinear.fit_common
  340.   .bilinear.fit_common:
  341.         mov     eax, [src_width_pixels]
  342.         mul     ebx
  343.         shr     eax, 16
  344.         mov     [scl_width_pixels], eax
  345.         imul    eax, [bytes_per_pixel]
  346.         mov     [scl_width_bytes], eax
  347.         mov     eax, [src_height_pixels]
  348.         mul     ebx
  349.         shr     eax, 16
  350.         mov     [scl_height_pixels], eax
  351.         jmp     .bilinear.common
  352.   .bilinear.stretch:
  353.         mov     eax, [_param1]
  354.         mov     [scl_width_pixels], eax
  355.         imul    eax, [bytes_per_pixel]
  356.         mov     [scl_width_bytes], eax
  357.         mov     ecx, [_param2]
  358.         mov     [scl_height_pixels], ecx
  359.         jmp     .bilinear.common
  360.  
  361.   .bilinear.common:
  362.         mov     eax, [_dst]
  363.         test    eax, eax
  364.         jnz     @f
  365.         stdcall img.create, [scl_width_pixels], [scl_height_pixels], [src_type]
  366.         test    eax, eax
  367.         jz      .error
  368.         mov     [_dst], eax
  369.     @@:
  370.         mov     edi, [eax + Image.Data]
  371.         mov     [dst_data], edi
  372.  
  373.         push    [_crop_width]
  374.         pop     [crop_width_pixels_m1]
  375.         sub     [crop_width_pixels_m1], 1
  376.         push    [_crop_height]
  377.         pop     [crop_height_pixels_m1]
  378.         sub     [crop_height_pixels_m1], 1
  379.  
  380.         mov     eax, 0xffffffff
  381.         xor     edx, edx
  382.         div     [scl_width_pixels]
  383.         mov     [scl_width_pixels_inv], eax
  384.         mov     eax, 0xffffffff
  385.         xor     edx, edx
  386.         div     [scl_height_pixels]
  387.         mov     [scl_height_pixels_inv], eax
  388.  
  389.         mov     eax, [src_type]
  390.         cmp     eax, Image.bpp8g
  391.         je      .bilinear.bpp8g
  392.         cmp     eax, Image.bpp24
  393.         je      .bilinear.bpp24
  394.         cmp     eax, Image.bpp32
  395.         je      .bilinear.bpp32
  396.         mov     ecx, LIBIMG_ERROR_BIT_DEPTH
  397.         jmp     .error
  398.  
  399.   .bilinear.bpp8g:
  400.         mov     esi, [src_data]
  401.         mov     [dst_y], 0
  402.         mov     eax, 0  ; mov eax, [dst_y]
  403.   .bilinear.bpp8g.line:
  404.         mov     esi, [src_data]
  405.         mov     [dst_x], 0
  406.         imul    eax, [crop_height_pixels_m1]
  407.         xor     edx, edx
  408.         div     [scl_height_pixels]
  409.         mov     [rem_y], edx
  410.         imul    eax, [src_width_bytes]
  411.         add     esi, eax
  412.         mov     [src_base], esi
  413.         mov     eax, 0  ; mov eax, [dst_x]
  414.  
  415.   .bilinear.bpp8g.pixel:
  416.         mov     esi, [src_base]
  417.  
  418.         imul    eax, [crop_width_pixels_m1]
  419.         xor     edx, edx
  420.         div     [scl_width_pixels]
  421.         add     esi, eax
  422.  
  423.         mov     ax, word[esi]
  424.         add     esi, [src_width_pixels]
  425.         mov     bx, word[esi]
  426.         mov     esi, edx
  427.         movzx   edx, ah
  428.         and     eax, 0x000000ff
  429.         movzx   ecx, bh
  430.         and     ebx, 0x000000ff
  431.  
  432.         imul    edx, esi
  433.         imul    ecx, esi
  434.         neg     esi
  435.         add     esi, [scl_width_pixels]
  436.         imul    eax, esi
  437.         imul    ebx, esi
  438.         add     eax, edx
  439.         add     ebx, ecx
  440.         mov     esi, [scl_width_pixels_inv]
  441.         mul     esi
  442.         mov     ecx, edx
  443.         mov     eax, ebx
  444.         mul     esi
  445.         mov     eax, edx
  446.  
  447.         mov     edx, [rem_y]
  448.         imul    eax, edx
  449.         neg     edx
  450.         add     edx, [scl_height_pixels]
  451.         imul    ecx, edx
  452.         add     eax, ecx
  453.         mul     [scl_height_pixels_inv]
  454.         mov     byte[edi], dl
  455.         add     edi, 1
  456.  
  457.         add     [dst_x], 1
  458.         mov     eax, [dst_x]
  459.         cmp     eax, [scl_width_pixels]
  460.         jne     .bilinear.bpp8g.pixel
  461.  
  462.         add     [dst_y], 1
  463.         mov     eax, [dst_y]
  464.         cmp     eax, [scl_height_pixels]
  465.         jne     .bilinear.bpp8g.line
  466.  
  467.         mov     eax, [_dst]
  468.         jmp     .quit
  469.  
  470.  
  471.   .bilinear.bpp24:
  472.         mov     esi, [src_data]
  473.         mov     [dst_y], 0
  474.         mov     eax, 0  ; mov eax, [dst_y]
  475.   .bilinear.bpp24.line:
  476.         mov     esi, [src_data]
  477.         mov     [dst_x], 0
  478.         imul    eax, [crop_height_pixels_m1]
  479.         xor     edx, edx
  480.         div     [scl_height_pixels]
  481.         mov     [rem_y], edx
  482.         imul    eax, [src_width_bytes]
  483.         add     esi, eax
  484.         mov     [src_base], esi
  485.         mov     eax, 0  ; mov eax, [dst_x]
  486.  
  487.   .bilinear.bpp24.pixel:
  488.         mov     esi, [src_base]
  489.  
  490.         imul    eax, [crop_width_pixels_m1]
  491.         xor     edx, edx
  492.         div     [scl_width_pixels]
  493.         lea     eax, [eax*3]
  494.         add     esi, eax
  495.  
  496.         mov     [rem_x], edx
  497.         sub     esi, 1
  498.         mov     [src_x], esi
  499.  
  500. repeat 3
  501.         mov     edx, [rem_x]
  502.         add     [src_x], 1
  503.         mov     esi, [src_x]
  504.  
  505.         mov     al, byte[esi]
  506.         mov     ah, byte[esi + 3]
  507.         add     esi, [src_width_bytes]
  508.         movzx   ebx, byte[esi]
  509.         movzx   ecx, byte[esi + 3]
  510.         mov     esi, edx
  511.         movzx   edx, ah
  512.         and     eax, 0x000000ff
  513.  
  514.         imul    edx, esi
  515.         imul    ecx, esi
  516.         neg     esi
  517.         add     esi, [scl_width_pixels]
  518.         imul    eax, esi
  519.         imul    ebx, esi
  520.         add     eax, edx
  521.         add     ebx, ecx
  522.         mov     esi, [scl_width_pixels_inv]
  523.         mul     esi
  524.         mov     ecx, edx
  525.         mov     eax, ebx
  526.         mul     esi
  527.         mov     eax, edx
  528.  
  529.         mov     edx, [rem_y]
  530.         imul    eax, edx
  531.         neg     edx
  532.         add     edx, [scl_height_pixels]
  533.         imul    ecx, edx
  534.         add     eax, ecx
  535.         mul     [scl_height_pixels_inv]
  536.         mov     byte[edi], dl
  537.         add     edi, 1
  538. end repeat
  539.  
  540.         add     [dst_x], 1
  541.         mov     eax, [dst_x]
  542.         cmp     eax, [scl_width_pixels]
  543.         jne     .bilinear.bpp24.pixel
  544.  
  545.         add     [dst_y], 1
  546.         mov     eax, [dst_y]
  547.         cmp     eax, [scl_height_pixels]
  548.         jne     .bilinear.bpp24.line
  549.  
  550.         mov     eax, [_dst]
  551.         jmp     .quit
  552.  
  553.   .bilinear.bpp32:
  554.         mov     esi, [src_data]
  555.         mov     [dst_y], 0
  556.         mov     eax, 0  ; mov eax, [dst_y]
  557.   .bilinear.bpp32.line:
  558.         mov     esi, [src_data]
  559.         mov     [dst_x], 0
  560.         imul    eax, [crop_height_pixels_m1]
  561.         xor     edx, edx
  562.         div     [scl_height_pixels]
  563.         mov     [rem_y], edx
  564.         imul    eax, [src_width_bytes]
  565.         add     esi, eax
  566.         mov     [src_base], esi
  567.         mov     eax, 0  ; mov eax, [dst_x]
  568.  
  569.   .bilinear.bpp32.pixel:
  570.         mov     esi, [src_base]
  571.  
  572.         imul    eax, [crop_width_pixels_m1]
  573.         xor     edx, edx
  574.         div     [scl_width_pixels]
  575.         shl     eax, 2
  576.         add     esi, eax
  577.  
  578.         mov     [rem_x], edx
  579.         sub     esi, 1
  580.         mov     [src_x], esi
  581.  
  582. repeat 4
  583.         mov     edx, [rem_x]
  584.         add     [src_x], 1
  585.         mov     esi, [src_x]
  586.  
  587.         mov     al, byte[esi]
  588.         mov     ah, byte[esi + 4]
  589.         add     esi, [src_width_bytes]
  590.         movzx   ebx, byte[esi]
  591.         movzx   ecx, byte[esi + 4]
  592.         mov     esi, edx
  593.         movzx   edx, ah
  594.         and     eax, 0x000000ff
  595.  
  596.         imul    edx, esi
  597.         imul    ecx, esi
  598.         neg     esi
  599.         add     esi, [scl_width_pixels]
  600.         imul    eax, esi
  601.         imul    ebx, esi
  602.         add     eax, edx
  603.         add     ebx, ecx
  604.         mov     esi, [scl_width_pixels_inv]
  605.         mul     esi
  606.         mov     ecx, edx
  607.         mov     eax, ebx
  608.         mul     esi
  609.         mov     eax, edx
  610.  
  611.         mov     edx, [rem_y]
  612.         imul    eax, edx
  613.         neg     edx
  614.         add     edx, [scl_height_pixels]
  615.         imul    ecx, edx
  616.         add     eax, ecx
  617.         mul     [scl_height_pixels_inv]
  618.         mov     byte[edi], dl
  619.         add     edi, 1
  620. end repeat
  621.  
  622.         add     [dst_x], 1
  623.         mov     eax, [dst_x]
  624.         cmp     eax, [scl_width_pixels]
  625.         jne     .bilinear.bpp32.pixel
  626.  
  627.         add     [dst_y], 1
  628.         mov     eax, [dst_y]
  629.         cmp     eax, [scl_height_pixels]
  630.         jne     .bilinear.bpp32.line
  631.  
  632.         mov     eax, [_dst]
  633.         jmp     .quit
  634.  
  635.  
  636.   .error:
  637.         xor     eax, eax
  638.   .quit:
  639.         ret
  640.  
  641. endp
  642.  
  643.