Subversion Repositories Kolibri OS

Rev

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

  1. ;;================================================================================================;;
  2. ;;//// ico.asm //// (c) mike.dld, 2007-2008, (c) diamond, 2009 ///////////////////////////////////;;
  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. ;; References:                                                                                    ;;
  21. ;;   1. "Icons in Win32"                                                                          ;;
  22. ;;      by John Hornick, Microsoft Corporation                                                    ;;
  23. ;;      http://msdn2.microsoft.com/en-us/library/ms997538.aspx                                    ;;
  24. ;;                                                                                                ;;
  25. ;;================================================================================================;;
  26.  
  27. include 'ico_cur.inc'
  28.  
  29. ;;================================================================================================;;
  30. ;;proc img.is.ico _data, _length ;////////////////////////////////////////////////////////////////;;
  31. img.is.ico:
  32.         mov     edx, 0x00010000 ; icon type = 1
  33.         jmp     @f
  34. img.is.cur:
  35.         mov     edx, 0x00020000 ; cursor type = 2
  36. @@:
  37. ;;------------------------------------------------------------------------------------------------;;
  38. ;? Determine if raw data could be decoded (is in ICO format)                                      ;;
  39. ;;------------------------------------------------------------------------------------------------;;
  40. ;> _data = raw data as read from file/stream                                                      ;;
  41. ;> _length = data length                                                                          ;;
  42. ;;------------------------------------------------------------------------------------------------;;
  43. ;< eax = false / true                                                                             ;;
  44. ;;================================================================================================;;
  45. ; test 1 (length of data): data must contain FileHeader
  46.         mov     ecx, [esp+8]
  47.         sub     ecx, sizeof.ico.FileHeader
  48.         jb      .nope
  49. ; test 2: signature
  50.         mov     eax, [esp+4]
  51.         cmp     dword [eax], edx        ; Reserved & Type
  52.         jne     .nope
  53. ; test 3: count must be non-zero
  54.         movzx   eax, [eax + ico.FileHeader.Count]
  55.         test    eax, eax
  56.         jz      .nope
  57. ; test 4 (length of data): data must containt Count dir entries
  58.         shl     eax, 4
  59.         sub     ecx, eax
  60.         jae     .yep
  61.  
  62.   .nope:
  63.         xor     eax, eax
  64.         ret     8
  65.  
  66.   .yep:
  67.         xor     eax, eax
  68.         inc     eax
  69.         ret     8
  70. ;endp
  71.  
  72. ;;================================================================================================;;
  73. proc img.decode.ico_cur _data, _length, _options ;////////////////////////////////////////////////;;
  74. ;;------------------------------------------------------------------------------------------------;;
  75. ;? Decode data into image if it contains correctly formed raw data in ICO/CUR format              ;;
  76. ;;------------------------------------------------------------------------------------------------;;
  77. ;> _data = raw data as read from file/stream                                                      ;;
  78. ;> _length = data length                                                                          ;;
  79. ;> _options = options for decoding (e.g. background color)                                        ;;
  80. ;;------------------------------------------------------------------------------------------------;;
  81. ;< eax = 0 (error) or pointer to image                                                            ;;
  82. ;;================================================================================================;;
  83. locals
  84.   count dd ?
  85.   img dd ?
  86.   main_img dd ?
  87. endl
  88.  
  89.         push    ebx esi edi
  90.  
  91. ; img.is.ico has been already called by img.decode
  92. ;       stdcall img.is.ico, [_data], [_length]
  93. ;       or      eax, eax
  94. ;       jz      .error
  95.  
  96.         mov     ebx, [_data]
  97.         movzx   eax, [ebx + ico.FileHeader.Count]
  98.         mov     [count], eax
  99.         and     [img], 0
  100.         and     [main_img], 0
  101. .loop:
  102.         mov     ecx, [ebx + sizeof.ico.FileHeader + ico.DirEntry.ByteSize]
  103.         mov     edx, [ebx + sizeof.ico.FileHeader + ico.DirEntry.ImageOffset]
  104.         mov     eax, [_length]
  105.         sub     eax, edx
  106.         jb      .skip
  107.         cmp     eax, ecx
  108.         jb      .skip
  109.         cmp     ecx, 12 ; length test, see img.is.bmp
  110.         jb      .skip
  111.         add     edx, [_data]
  112.         push    [_options]
  113.         push    ecx
  114.         push    edx
  115.         call    img.decode.ico._.decode_icon_data
  116.         test    eax, eax
  117.         jz      .skip
  118.         push    0xFFFFFF        ; set bgr to white if no given
  119.         mov     edx, [_options]
  120.         test    edx, edx
  121.         jz      @f
  122.         cmp     [edx + ImageDecodeOptions.UsedSize], ImageDecodeOptions.BackgroundColor + 4
  123.         jb      @f
  124.         add     esp, 4
  125.         push    [edx + ImageDecodeOptions.BackgroundColor]
  126. @@:
  127.         call    img.decode.ico._.decode_icon_mask
  128.         test    eax, eax
  129.         jz      .skip
  130.         mov     edx, [img]
  131.         test    edx, edx
  132.         jz      .first
  133.         mov     [edx + Image.Next], eax
  134.         mov     [eax + Image.Previous], edx
  135.         jmp     @f
  136. .first:
  137.         mov     [main_img], eax
  138. @@:
  139.         mov     [img], eax
  140. .skip:
  141.         add     ebx, sizeof.ico.DirEntry
  142.         dec     [count]
  143.         jnz     .loop
  144.  
  145.         mov     eax, [main_img]
  146.         pop     edi esi ebx
  147.         ret
  148. endp
  149.  
  150. ;;================================================================================================;;
  151. img.encode.cur:
  152. proc img.encode.ico _img, _p_length, _options ;///////////////////////////////////////////////////;;
  153. ;;------------------------------------------------------------------------------------------------;;
  154. ;? Encode image into raw data in ICO format                                                       ;;
  155. ;;------------------------------------------------------------------------------------------------;;
  156. ;> _img = pointer to image                                                                        ;;
  157. ;;------------------------------------------------------------------------------------------------;;
  158. ;< eax = 0 (error) or pointer to encoded data                                                     ;;
  159. ;< _p_length = encoded data length                                                                ;;
  160. ;;================================================================================================;;
  161.         xor     eax, eax
  162.         ret
  163. endp
  164.  
  165.  
  166. ;;================================================================================================;;
  167. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  168. ;;================================================================================================;;
  169. ;! Below are private procs you should never call directly from your code                          ;;
  170. ;;================================================================================================;;
  171. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  172. ;;================================================================================================;;
  173.  
  174. img.decode.ico._.decode_icon_data:
  175. ; create stack frame and jump to common BMP+ICO code
  176.         push    ebp
  177.         mov     ebp, esp
  178.         sub     esp, 12
  179.         mov     byte [ebp - 3], 1       ; bIsIco
  180.         jmp     img.decode.bmp.common
  181.  
  182. img.decode.ico._.decode_icon_mask:
  183.         mov     edx, [eax + Image.Width]
  184.         add     edx, 31
  185.         shr     edx, 3
  186.         and     edx, not 3
  187.         push    edx
  188.         imul    edx, [eax + Image.Height]
  189.         cmp     ecx, edx
  190.         pop     edx
  191.         jb      .error.free
  192.         mov     edi, [eax + Image.Data]
  193.         push    ebp ebx eax
  194.         xor     ebp, ebp
  195.         mov     ebx, [eax + Image.Extended]
  196.         cmp     [ebx + bmp.Image.info.Height], 0
  197.         js      @f
  198.         push    edx
  199.         imul    edx, [eax + Image.Height]
  200.         add     esi, edx
  201.         pop     edx
  202.         lea     ebp, [edx+edx]
  203.         sub     esi, edx
  204. @@:
  205.         mov     ebx, [eax + Image.Height]
  206.         mov     ecx, [eax + Image.Width]
  207. ; for now, BMP code produces only 8 and 32 bpp images
  208.         cmp     [eax + Image.Type], Image.bpp8
  209.         jz      .bpp8
  210. .bpp32:
  211.         mov     edx, [esp+16]   ; get background color
  212. .bpp32.extloop:
  213.         push    ecx
  214. .bpp32.innloop:
  215.         lodsd
  216.         bswap   eax
  217.         push    32
  218. .bpp32.dwordloop:
  219.         add     eax, eax
  220.         jnc     @f
  221.         mov     [edi], edx
  222. @@:
  223.         add     edi, 4
  224.         dec     ecx
  225.         jz      @f
  226.         dec     dword [esp]
  227.         jnz     .bpp32.dwordloop
  228. @@:
  229.         pop     eax
  230.         test    ecx, ecx
  231.         jnz     .bpp32.innloop
  232.         sub     esi, ebp
  233.         pop     ecx
  234.         dec     ebx
  235.         jnz     .bpp32.extloop
  236.         pop     eax ebx ebp
  237.         ret     4
  238. .bpp8:
  239.         push    edi
  240.         mov     edi, [eax + Image.Palette]
  241.         mov     eax, [esp+20]   ; get background color
  242. ; if palette already has index for bgr color, use it
  243.         push    ecx
  244.         mov     ecx, 256
  245.         repnz   scasd
  246.         jnz     .bpp8.notfound
  247.         not     cl      ; cl = index
  248.         pop     edx
  249.         pop     edi
  250. .bpp8.extloop:
  251.         push    edx
  252. .bpp8.innloop:
  253.         lodsd
  254.         bswap   eax
  255.         push    32
  256. .bpp8.dwordloop:
  257.         add     eax, eax
  258.         jnc     @f
  259.         mov     [edi], cl
  260. @@:
  261.         inc     edi
  262.         dec     edx
  263.         jz      @f
  264.         dec     dword [esp]
  265.         jnz     .bpp8.dwordloop
  266. @@:
  267.         pop     eax
  268.         test    edx, edx
  269.         jnz     .bpp8.innloop
  270.         sub     esi, ebp
  271.         pop     edx
  272.         dec     ebx
  273.         jnz     .bpp8.extloop
  274.         pop     eax ebx ebp
  275.         ret     4
  276. .bpp8.notfound:
  277. ; get maximum used color; if index < 255, then we can add one color to palette
  278.         pop     ecx
  279.         pop     edi
  280.         pop     eax
  281.         mov     edx, [eax + Image.Width]
  282.         imul    edx, ebx
  283.         mov     edi, [eax + Image.Data]
  284.         xor     ecx, ecx
  285. .bpp8.scanloop:
  286.         cmp     [edi], cl
  287.         jb      @f
  288.         mov     cl, [edi]
  289. @@:
  290.         inc     edi
  291.         dec     edx
  292.         jnz     .bpp8.scanloop
  293.         inc     cl
  294.         jz      .bpp8.nospace
  295.         mov     edx, [esp+8]
  296.         mov     edi, [eax + Image.Palette]
  297.         mov     [edi+ecx*4], edx        ; set palette color
  298.         mov     edi, [eax + Image.Data]
  299.         mov     edx, [eax + Image.Width]
  300.         push    eax
  301.         jmp     .bpp8.extloop
  302. .bpp8.nospace:
  303. ; convert to 24 bpp
  304.         mov     edx, [eax + Image.Width]
  305.         imul    edx, ebx
  306.         lea     edx, [edx*3]
  307.         push    eax
  308.         invoke  mem.alloc, edx
  309.         mov     edi, eax
  310.         pop     eax
  311.         test    edi, edi
  312.         jz      .error.free2
  313.         push    eax esi edi
  314.         mov     esi, eax
  315.         call    img._.do_rgb
  316.         pop     edi esi eax
  317.         xchg    edi, [eax + Image.Data]
  318.         mov     byte [eax + Image.Type], Image.bpp24
  319.         push    eax
  320.         invoke  mem.free, edi
  321.         pop     eax
  322.         push    eax
  323.         mov     ecx, [eax + Image.Width]
  324. .bpp24:
  325.         mov     edx, [esp+16]   ; get background color
  326. .bpp24.extloop:
  327.         push    ecx
  328. .bpp24.innloop:
  329.         lodsd
  330.         bswap   eax
  331.         push    32
  332. .bpp24.dwordloop:
  333.         add     eax, eax
  334.         jnc     @f
  335.         mov     [edi], dx
  336.         ror     edx, 16
  337.         mov     [edi+2], dl
  338.         ror     edx, 16
  339. @@:
  340.         add     edi, 4
  341.         dec     ecx
  342.         jz      @f
  343.         dec     dword [esp]
  344.         jnz     .bpp24.dwordloop
  345. @@:
  346.         pop     eax
  347.         test    ecx, ecx
  348.         jnz     .bpp24.innloop
  349.         sub     esi, ebp
  350.         pop     ecx
  351.         dec     ebx
  352.         jnz     .bpp24.extloop
  353.         pop     eax ebx ebp
  354.         ret     4
  355. .error.free2:
  356.         pop     ebx ebp
  357. .error.free:
  358.         stdcall img._.delete, eax
  359.         xor     eax, eax
  360.         ret     4
  361.  
  362. ;;================================================================================================;;
  363. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  364. ;;================================================================================================;;
  365. ;! Below is private data you should never use directly from your code                             ;;
  366. ;;================================================================================================;;
  367. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  368. ;;================================================================================================;;
  369.  
  370.  
  371. ;
  372.