Subversion Repositories Kolibri OS

Rev

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

  1. ;;================================================================================================;;
  2. ;;//// libimg.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.  
  21. format MS COFF
  22.  
  23. public @EXPORT as 'EXPORTS'
  24.  
  25. include '../../../../struct.inc'
  26. include '../../../../proc32.inc'
  27. include '../../../../macros.inc'
  28. purge section,mov,add,sub
  29.  
  30. include 'libimg.inc'
  31.  
  32. section '.flat' code readable align 16
  33.  
  34. include 'bmp/bmp.asm'
  35. include 'gif/gif.asm'
  36. include 'jpeg/jpeg.asm'
  37. include 'png/png.asm'
  38. include 'tga/tga.asm'
  39. include 'z80/z80.asm'
  40. include 'ico_cur/ico_cur.asm'
  41.  
  42. ;;================================================================================================;;
  43. proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
  44. ;;------------------------------------------------------------------------------------------------;;
  45. ;? Library entry point (called after library load)                                                ;;
  46. ;;------------------------------------------------------------------------------------------------;;
  47. ;> eax = pointer to memory allocation routine                                                     ;;
  48. ;> ebx = pointer to memory freeing routine                                                        ;;
  49. ;> ecx = pointer to memory reallocation routine                                                   ;;
  50. ;> edx = pointer to library loading routine                                                       ;;
  51. ;;------------------------------------------------------------------------------------------------;;
  52. ;< eax = 1 (fail) / 0 (ok) (library initialization result)                                        ;;
  53. ;;================================================================================================;;
  54.         mov     [mem.alloc], eax
  55.         mov     [mem.free], ebx
  56.         mov     [mem.realloc], ecx
  57.         mov     [dll.load], edx
  58.  
  59.         call    img.initialize.jpeg
  60.  
  61.         xor     eax, eax
  62.         cpuid
  63.         cmp     ecx, 'ntel'
  64.         jnz     @f
  65.         mov     dword [img._.do_rgb.handlers + (Image.bpp15-1)*4], img._.do_rgb.bpp15.intel
  66.         mov     dword [img._.do_rgb.handlers + (Image.bpp16-1)*4], img._.do_rgb.bpp16.intel
  67.   @@:
  68.  
  69.   .ok:  xor     eax,eax
  70.         ret
  71. endp
  72.  
  73. ;;================================================================================================;;
  74. proc img.is_img _data, _length ;//////////////////////////////////////////////////////////////////;;
  75. ;;------------------------------------------------------------------------------------------------;;
  76. ;? --- TBD ---                                                                                    ;;
  77. ;;------------------------------------------------------------------------------------------------;;
  78. ;> --- TBD ---                                                                                    ;;
  79. ;;------------------------------------------------------------------------------------------------;;
  80. ;< --- TBD ---                                                                                    ;;
  81. ;;================================================================================================;;
  82.         push    ebx
  83.         mov     ebx, img._.formats_table
  84.     @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
  85.         or      eax, eax
  86.         jnz     @f
  87.         add     ebx, sizeof.FormatsTableEntry
  88.         cmp     dword[ebx], 0
  89.         jnz     @b
  90.         xor     eax, eax
  91.     @@: pop     ebx
  92.         ret
  93. endp
  94.  
  95. ;;================================================================================================;;
  96. proc img.info _data, _length ;////////////////////////////////////////////////////////////////////;;
  97. ;;------------------------------------------------------------------------------------------------;;
  98. ;? --- TBD ---                                                                                    ;;
  99. ;;------------------------------------------------------------------------------------------------;;
  100. ;> --- TBD ---                                                                                    ;;
  101. ;;------------------------------------------------------------------------------------------------;;
  102. ;< --- TBD ---                                                                                    ;;
  103. ;;================================================================================================;;
  104.         xor     eax, eax
  105.         ret
  106. endp
  107.  
  108. ;;================================================================================================;;
  109. proc img.from_file _filename ;////////////////////////////////////////////////////////////////////;;
  110. ;;------------------------------------------------------------------------------------------------;;
  111. ;? --- TBD ---                                                                                    ;;
  112. ;;------------------------------------------------------------------------------------------------;;
  113. ;> --- TBD ---                                                                                    ;;
  114. ;;------------------------------------------------------------------------------------------------;;
  115. ;< eax = 0 / pointer to image                                                                     ;;
  116. ;;================================================================================================;;
  117.         xor     eax, eax
  118.         ret
  119. endp
  120.  
  121. ;;================================================================================================;;
  122. proc img.to_file _img, _filename ;////////////////////////////////////////////////////////////////;;
  123. ;;------------------------------------------------------------------------------------------------;;
  124. ;? --- TBD ---                                                                                    ;;
  125. ;;------------------------------------------------------------------------------------------------;;
  126. ;> --- TBD ---                                                                                    ;;
  127. ;;------------------------------------------------------------------------------------------------;;
  128. ;< eax = false / true                                                                             ;;
  129. ;;================================================================================================;;
  130.         xor     eax, eax
  131.         ret
  132. endp
  133.  
  134. ;;================================================================================================;;
  135. proc img.from_rgb _rgb_data ;/////////////////////////////////////////////////////////////////////;;
  136. ;;------------------------------------------------------------------------------------------------;;
  137. ;? --- TBD ---                                                                                    ;;
  138. ;;------------------------------------------------------------------------------------------------;;
  139. ;> --- TBD ---                                                                                    ;;
  140. ;;------------------------------------------------------------------------------------------------;;
  141. ;< eax = 0 / pointer to image                                                                     ;;
  142. ;;================================================================================================;;
  143.         xor     eax, eax
  144.         ret
  145. endp
  146.  
  147. ;;================================================================================================;;
  148. proc img.to_rgb2 _img, _out ;/////////////////////////////////////////////////////////////////////;;
  149. ;;------------------------------------------------------------------------------------------------;;
  150. ;? --- TBD ---                                                                                    ;;
  151. ;;------------------------------------------------------------------------------------------------;;
  152. ;> --- TBD ---                                                                                    ;;
  153. ;;------------------------------------------------------------------------------------------------;;
  154. ;< --- TBD ---                                                                                    ;;
  155. ;;================================================================================================;;
  156.         push    esi edi
  157.         mov     esi, [_img]
  158.         stdcall img._.validate, esi
  159.         or      eax, eax
  160.         jnz     .ret
  161.         mov     edi, [_out]
  162.         call    img._.do_rgb
  163. .ret:
  164.         pop     edi esi
  165.         ret
  166. endp
  167.  
  168. ;;================================================================================================;;
  169. proc img.to_rgb _img ;////////////////////////////////////////////////////////////////////////////;;
  170. ;;------------------------------------------------------------------------------------------------;;
  171. ;? --- TBD ---                                                                                    ;;
  172. ;;------------------------------------------------------------------------------------------------;;
  173. ;> --- TBD ---                                                                                    ;;
  174. ;;------------------------------------------------------------------------------------------------;;
  175. ;< eax = 0 / pointer to rgb_data (array of [rgb] triplets)                                        ;;
  176. ;;================================================================================================;;
  177.         push    esi edi
  178.         mov     esi, [_img]
  179.         stdcall img._.validate, esi
  180.         or      eax, eax
  181.         jnz     .error
  182.  
  183.         mov     esi, [_img]
  184.         mov     ecx, [esi + Image.Width]
  185.         imul    ecx, [esi + Image.Height]
  186.         lea     eax, [ecx * 3 + 4 * 3]
  187.         invoke  mem.alloc, eax
  188.         or      eax, eax
  189.         jz      .error
  190.  
  191.         mov     edi, eax
  192.         push    eax
  193.         mov     eax, [esi + Image.Width]
  194.         stosd
  195.         mov     eax, [esi + Image.Height]
  196.         stosd
  197.         call    img._.do_rgb
  198.         pop     eax
  199.         pop     edi esi
  200.         ret
  201.  
  202.   .error:
  203.         xor     eax, eax
  204.         pop     edi esi
  205.         ret
  206. endp
  207.  
  208. ;;================================================================================================;;
  209. proc img._.do_rgb ;///////////////////////////////////////////////////////////////////////////////;;
  210. ;;------------------------------------------------------------------------------------------------;;
  211. ;? --- TBD ---                                                                                    ;;
  212. ;;------------------------------------------------------------------------------------------------;;
  213. ;> --- TBD ---                                                                                    ;;
  214. ;;------------------------------------------------------------------------------------------------;;
  215. ;< --- TBD ---                                                                                    ;;
  216. ;;================================================================================================;;
  217.         mov     ecx, [esi + Image.Width]
  218.         imul    ecx, [esi + Image.Height]
  219.         mov     eax, [esi + Image.Type]
  220.         jmp     dword [.handlers + (eax-1)*4]
  221.  
  222. align 16
  223. .bpp8:
  224. ; 8 BPP -> 24 BPP
  225.         push    ebx
  226.         mov     ebx, [esi + Image.Palette]
  227.         mov     esi, [esi + Image.Data]
  228. @@:
  229.         movzx   eax, byte [esi]
  230.         add     esi, 1
  231.         mov     eax, [ebx + eax*4]
  232.         mov     [edi], eax
  233.         add     edi, 3
  234.         sub     ecx, 1
  235.         jnz     @b
  236.         pop     ebx
  237.         ret
  238.  
  239. ; 15 BPP -> 24 BPP
  240. .bpp15.intel:
  241.         push    ebx ebp
  242.         sub     ecx, 4
  243.         jb      .bpp15.tail
  244. align 16
  245. .bpp15.intel.loop:
  246. repeat 2
  247.         mov     ebx, [esi]
  248.         mov     al, [esi]
  249.         mov     ah, [esi+1]
  250.         add     esi, 4
  251.         and     al, 0x1F
  252.         and     ah, 0x1F shl 2
  253.         mov     ebp, ebx
  254.         mov     dl, al
  255.         mov     dh, ah
  256.         shr     al, 2
  257.         shr     ah, 4
  258.         shl     dl, 3
  259.         shl     dh, 1
  260.         and     ebp, 0x1F shl 5
  261.         add     al, dl
  262.         add     ah, dh
  263.         shr     ebp, 2
  264.         mov     [edi], al
  265.         mov     [edi+2], ah
  266.         mov     eax, ebx
  267.         mov     ebx, ebp
  268.         shr     eax, 16
  269.         shr     ebx, 5
  270.         add     ebx, ebp
  271.         mov     ebp, eax
  272.         mov     [edi+1], bl
  273.         and     eax, (0x1F) or (0x1F shl 10)
  274.         and     ebp, 0x1F shl 5
  275.         lea     edx, [eax+eax]
  276.         shr     al, 2
  277.         mov     ebx, ebp
  278.         shr     ah, 4
  279.         shl     dl, 2
  280.         shr     ebx, 2
  281.         shr     ebp, 7
  282.         add     al, dl
  283.         add     ah, dh
  284.         mov     [edi+3], al
  285.         add     ebx, ebp
  286.         mov     [edi+5], ah
  287.         mov     [edi+4], bl
  288.         add     edi, 6
  289. end repeat
  290.         sub     ecx, 4
  291.         jnb     .bpp15.intel.loop
  292. .bpp15.tail:
  293.         add     ecx, 4
  294.         jz      .bpp15.done
  295. @@:
  296.         movzx   eax, word [esi]
  297.         mov     ebx, eax
  298.         add     esi, 2
  299.         and     eax, (0x1F) or (0x1F shl 10)
  300.         and     ebx, 0x1F shl 5
  301.         lea     edx, [eax+eax]
  302.         shr     al, 2
  303.         mov     ebp, ebx
  304.         shr     ebx, 2
  305.         shr     ah, 4
  306.         shl     dl, 2
  307.         shr     ebp, 7
  308.         add     eax, edx
  309.         add     ebx, ebp
  310.         mov     [edi], al
  311.         mov     [edi+1], bl
  312.         mov     [edi+2], ah
  313.         add     edi, 3
  314.         sub     ecx, 1
  315.         jnz     @b
  316. .bpp15.done:
  317.         pop     ebp ebx
  318.         ret
  319.  
  320. .bpp15.amd:
  321.         push    ebx ebp
  322.         sub     ecx, 4
  323.         jb      .bpp15.tail
  324. align 16
  325. .bpp15.amd.loop:
  326. repeat 4
  327. if (% mod 2) = 1
  328.         mov     eax, dword [esi]
  329.         mov     ebx, dword [esi]
  330. else
  331.         movzx   eax, word [esi]
  332.         mov     ebx, eax
  333. end if
  334.         add     esi, 2
  335.         and     eax, (0x1F) or (0x1F shl 10)
  336.         and     ebx, 0x1F shl 5
  337.         lea     edx, [eax+eax]
  338.         shr     al, 2
  339.         mov     ebp, ebx
  340.         shr     ebx, 2
  341.         shr     ah, 4
  342.         shl     dl, 2
  343.         shr     ebp, 7
  344.         add     eax, edx
  345.         add     ebx, ebp
  346.         mov     [edi], al
  347.         mov     [edi+1], bl
  348.         mov     [edi+2], ah
  349.         add     edi, 3
  350. end repeat
  351.         sub     ecx, 4
  352.         jnb     .bpp15.amd.loop
  353.         jmp     .bpp15.tail
  354.  
  355. ; 16 BPP -> 24 BPP
  356. .bpp16.intel:
  357.         push    ebx ebp
  358.         sub     ecx, 4
  359.         jb      .bpp16.tail
  360. align 16
  361. .bpp16.intel.loop:
  362. repeat 2
  363.         mov     ebx, [esi]
  364.         mov     al, [esi]
  365.         mov     ah, [esi+1]
  366.         add     esi, 4
  367.         and     al, 0x1F
  368.         and     ah, 0x1F shl 3
  369.         mov     ebp, ebx
  370.         mov     dl, al
  371.         mov     dh, ah
  372.         shr     al, 2
  373.         shr     ah, 5
  374.         shl     dl, 3
  375.         and     ebp, 0x3F shl 5
  376.         add     al, dl
  377.         add     ah, dh
  378.         shr     ebp, 3
  379.         mov     [edi], al
  380.         mov     [edi+2], ah
  381.         mov     eax, ebx
  382.         mov     ebx, ebp
  383.         shr     eax, 16
  384.         shr     ebx, 6
  385.         add     ebx, ebp
  386.         mov     ebp, eax
  387.         mov     [edi+1], bl
  388.         and     eax, (0x1F) or (0x1F shl 11)
  389.         and     ebp, 0x3F shl 5
  390.         mov     edx, eax
  391.         shr     al, 2
  392.         mov     ebx, ebp
  393.         shr     ah, 5
  394.         shl     dl, 3
  395.         shr     ebx, 3
  396.         shr     ebp, 9
  397.         add     al, dl
  398.         add     ah, dh
  399.         mov     [edi+3], al
  400.         add     ebx, ebp
  401.         mov     [edi+5], ah
  402.         mov     [edi+4], bl
  403.         add     edi, 6
  404. end repeat
  405.         sub     ecx, 4
  406.         jnb     .bpp16.intel.loop
  407. .bpp16.tail:
  408.         add     ecx, 4
  409.         jz      .bpp16.done
  410. @@:
  411.         movzx   eax, word [esi]
  412.         mov     ebx, eax
  413.         add     esi, 2
  414.         and     eax, (0x1F) or (0x1F shl 11)
  415.         and     ebx, 0x3F shl 5
  416.         mov     edx, eax
  417.         shr     al, 2
  418.         mov     ebp, ebx
  419.         shr     ebx, 3
  420.         shr     ah, 5
  421.         shl     dl, 3
  422.         shr     ebp, 9
  423.         add     eax, edx
  424.         add     ebx, ebp
  425.         mov     [edi], al
  426.         mov     [edi+1], bl
  427.         mov     [edi+2], ah
  428.         add     edi, 3
  429.         sub     ecx, 1
  430.         jnz     @b
  431. .bpp16.done:
  432.         pop     ebp ebx
  433.         ret
  434.  
  435. .bpp16.amd:
  436.         push    ebx ebp
  437.         sub     ecx, 4
  438.         jb      .bpp16.tail
  439. align 16
  440. .bpp16.amd.loop:
  441. repeat 4
  442. if (% mod 2) = 1
  443.         mov     eax, dword [esi]
  444.         mov     ebx, dword [esi]
  445. else
  446.         movzx   eax, word [esi]
  447.         mov     ebx, eax
  448. end if
  449.         add     esi, 2
  450.         and     eax, (0x1F) or (0x1F shl 11)
  451.         and     ebx, 0x3F shl 5
  452.         mov     edx, eax
  453.         shr     al, 2
  454.         mov     ebp, ebx
  455.         shr     ebx, 3
  456.         shr     ah, 5
  457.         shl     dl, 3
  458.         shr     ebp, 9
  459.         add     eax, edx
  460.         add     ebx, ebp
  461.         mov     [edi], al
  462.         mov     [edi+1], bl
  463.         mov     [edi+2], ah
  464.         add     edi, 3
  465. end repeat
  466.         sub     ecx, 4
  467.         jnb     .bpp16.amd.loop
  468.         jmp     .bpp16.tail
  469.  
  470. align 16
  471. .bpp24:
  472. ; 24 BPP -> 24 BPP
  473.         lea     ecx, [ecx*3 + 3]
  474.         mov     esi, [esi + Image.Data]
  475.         shr     ecx, 2
  476.         rep     movsd
  477.         ret
  478.  
  479. align 16
  480. .bpp32:
  481. ; 32 BPP -> 24 BPP
  482.         mov     esi, [esi + Image.Data]
  483.  
  484.     @@:
  485.         mov     eax, [esi]
  486.         mov     [edi], ax
  487.         shr     eax, 16
  488.         mov     [edi+2], al
  489.         add     esi, 4
  490.         add     edi, 3
  491.         sub     ecx, 1
  492.         jnz     @b
  493.  
  494.     @@:
  495.         ret
  496.  
  497. endp
  498.  
  499. ;;================================================================================================;;
  500. proc img.decode _data, _length, _options ;////////////////////////////////////////////////////////;;
  501. ;;------------------------------------------------------------------------------------------------;;
  502. ;? --- TBD ---                                                                                    ;;
  503. ;;------------------------------------------------------------------------------------------------;;
  504. ;> --- TBD ---                                                                                    ;;
  505. ;;------------------------------------------------------------------------------------------------;;
  506. ;< eax = 0 / pointer to image                                                                     ;;
  507. ;;================================================================================================;;
  508.         push    ebx
  509.         mov     ebx, img._.formats_table
  510.     @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
  511.         or      eax, eax
  512.         jnz     @f
  513.         add     ebx, sizeof.FormatsTableEntry
  514.         cmp     dword[ebx], eax ;0
  515.         jnz     @b
  516.         pop     ebx
  517.         ret
  518.     @@: mov     eax, [ebx + FormatsTableEntry.Decode]
  519.         pop     ebx
  520.         leave
  521.         jmp     eax
  522. endp
  523.  
  524. ;;================================================================================================;;
  525. proc img.encode _img, _p_length, _options ;///////////////////////////////////////////////////////;;
  526. ;;------------------------------------------------------------------------------------------------;;
  527. ;? --- TBD ---                                                                                    ;;
  528. ;;------------------------------------------------------------------------------------------------;;
  529. ;> --- TBD ---                                                                                    ;;
  530. ;;------------------------------------------------------------------------------------------------;;
  531. ;< eax = 0 / pointer to encoded data                                                              ;;
  532. ;< [_p_length] = data length                                                                      ;;
  533. ;;================================================================================================;;
  534.         xor     eax, eax
  535.         ret
  536. endp
  537.  
  538. ;;================================================================================================;;
  539. proc img.create _width, _height, _type ;//////////////////////////////////////////////////////////;;
  540. ;;------------------------------------------------------------------------------------------------;;
  541. ;? --- TBD ---                                                                                    ;;
  542. ;;------------------------------------------------------------------------------------------------;;
  543. ;> --- TBD ---                                                                                    ;;
  544. ;;------------------------------------------------------------------------------------------------;;
  545. ;< eax = 0 / pointer to image                                                                     ;;
  546. ;;================================================================================================;;
  547.         push    ecx
  548.  
  549.         stdcall img._.new
  550.         or      eax, eax
  551.         jz      .error
  552.  
  553.         mov     ecx, [_type]
  554.         mov     [eax + Image.Type], ecx
  555.  
  556.         push    eax
  557.  
  558.         stdcall img._.resize_data, eax, [_width], [_height]
  559.         or      eax, eax
  560.         jz      .error.2
  561.  
  562.         pop     eax
  563.         jmp     .ret
  564.  
  565.   .error.2:
  566. ;       pop     eax
  567.         stdcall img._.delete; eax
  568.         xor     eax, eax
  569.  
  570.   .error:
  571.   .ret:
  572.         pop     ecx
  573.         ret
  574. endp
  575.  
  576. ;;================================================================================================;;
  577. proc img.destroy.layer _img ;/////////////////////////////////////////////////////////////////////;;
  578. ;;------------------------------------------------------------------------------------------------;;
  579. ;? --- TBD ---                                                                                    ;;
  580. ;;------------------------------------------------------------------------------------------------;;
  581. ;> --- TBD ---                                                                                    ;;
  582. ;;------------------------------------------------------------------------------------------------;;
  583. ;< eax = false / true                                                                             ;;
  584. ;;================================================================================================;;
  585.         mov     eax, [_img]
  586.         mov     edx, [eax + Image.Previous]
  587.         test    edx, edx
  588.         jz      @f
  589.         push    [eax + Image.Next]
  590.         pop     [edx + Image.Next]
  591. @@:
  592.         mov     edx, [eax + Image.Next]
  593.         test    edx, edx
  594.         jz      @f
  595.         push    [eax + Image.Previous]
  596.         pop     [edx + Image.Previous]
  597. @@:
  598.         stdcall img._.delete, eax
  599.         ret
  600. endp
  601.  
  602. ;;================================================================================================;;
  603. proc img.destroy _img ;///////////////////////////////////////////////////////////////////////////;;
  604. ;;------------------------------------------------------------------------------------------------;;
  605. ;? --- TBD ---                                                                                    ;;
  606. ;;------------------------------------------------------------------------------------------------;;
  607. ;> --- TBD ---                                                                                    ;;
  608. ;;------------------------------------------------------------------------------------------------;;
  609. ;< eax = false / true                                                                             ;;
  610. ;;================================================================================================;;
  611.         push    1
  612.         mov     eax, [_img]
  613.         mov     eax, [eax + Image.Previous]
  614. .destroy_prev_loop:
  615.         test    eax, eax
  616.         jz      .destroy_prev_done
  617.         pushd   [eax + Image.Previous]
  618.         stdcall img._.delete, eax
  619.         test    eax, eax
  620.         jnz     @f
  621.         mov     byte [esp+4], 0
  622. @@:
  623.         pop     eax
  624.         jmp     .destroy_prev_loop
  625. .destroy_prev_done:
  626.         mov     eax, [_img]
  627. .destroy_next_loop:
  628.         pushd   [eax + Image.Next]
  629.         stdcall img._.delete, eax
  630.         test    eax, eax
  631.         jnz     @f
  632.         mov     byte [esp+4], 0
  633. @@:
  634.         pop     eax
  635.         test    eax, eax
  636.         jnz     .destroy_next_loop
  637.         pop     eax
  638.         ret
  639. endp
  640.  
  641. ;;================================================================================================;;
  642. proc img.count _img ;/////////////////////////////////////////////////////////////////////////////;;
  643. ;;------------------------------------------------------------------------------------------------;;
  644. ;? Get number of images in the list (e.g. in animated GIF file)                                   ;;
  645. ;;------------------------------------------------------------------------------------------------;;
  646. ;> _img = pointer to image                                                                        ;;
  647. ;;------------------------------------------------------------------------------------------------;;
  648. ;< eax = -1 (fail) / >0 (ok)                                                                      ;;
  649. ;;================================================================================================;;
  650.         push    ecx edx
  651.         mov     edx, [_img]
  652.         stdcall img._.validate, edx
  653.         or      eax, eax
  654.         jnz     .error
  655.  
  656.     @@: mov     eax, [edx + Image.Previous]
  657.         or      eax, eax
  658.         jz      @f
  659.         mov     edx, eax
  660.         jmp     @b
  661.  
  662.     @@: xor     ecx, ecx
  663.     @@: inc     ecx
  664.         mov     eax, [edx + Image.Next]
  665.         or      eax, eax
  666.         jz      .exit
  667.         mov     edx, eax
  668.         jmp     @b
  669.  
  670.   .exit:
  671.         mov     eax, ecx
  672.         pop     edx ecx
  673.         ret
  674.  
  675.   .error:
  676.         or      eax, -1
  677.         pop     edx ecx
  678.         ret
  679. endp
  680.  
  681. ;;//// image processing //////////////////////////////////////////////////////////////////////////;;
  682.  
  683. ;;================================================================================================;;
  684. proc img.lock_bits _img, _start_line, _end_line ;/////////////////////////////////////////////////;;
  685. ;;------------------------------------------------------------------------------------------------;;
  686. ;? --- TBD ---                                                                                    ;;
  687. ;;------------------------------------------------------------------------------------------------;;
  688. ;> --- TBD ---                                                                                    ;;
  689. ;;------------------------------------------------------------------------------------------------;;
  690. ;< eax = 0 / pointer to bits                                                                      ;;
  691. ;;================================================================================================;;
  692.         xor     eax, eax
  693.         ret
  694. endp
  695.  
  696. ;;================================================================================================;;
  697. proc img.unlock_bits _img, _lock ;////////////////////////////////////////////////////////////////;;
  698. ;;------------------------------------------------------------------------------------------------;;
  699. ;? --- TBD ---                                                                                    ;;
  700. ;;------------------------------------------------------------------------------------------------;;
  701. ;> --- TBD ---                                                                                    ;;
  702. ;;------------------------------------------------------------------------------------------------;;
  703. ;< eax = false / true                                                                             ;;
  704. ;;================================================================================================;;
  705.         xor     eax, eax
  706.         ret
  707. endp
  708.  
  709. ;;================================================================================================;;
  710. proc img.flip.layer _img, _flip_kind ;////////////////////////////////////////////////////////////;;
  711. ;;------------------------------------------------------------------------------------------------;;
  712. ;? Flip image layer                                                                               ;;
  713. ;;------------------------------------------------------------------------------------------------;;
  714. ;> _img = pointer to image                                                                        ;;
  715. ;> _flip_kind = one of FLIP_* constants                                                           ;;
  716. ;;------------------------------------------------------------------------------------------------;;
  717. ;< eax = false / true                                                                             ;;
  718. ;;================================================================================================;;
  719. locals
  720.   scanline_len dd ?
  721. endl
  722.  
  723.         push    ebx esi edi
  724.         mov     ebx, [_img]
  725.         stdcall img._.validate, ebx
  726.         or      eax, eax
  727.         jnz     .error
  728.  
  729.         mov     ecx, [ebx + Image.Height]
  730.         mov     eax, [ebx + Image.Width]
  731.         call    img._.get_scanline_len
  732.         mov     [scanline_len], eax
  733.  
  734.         test    [_flip_kind], FLIP_VERTICAL
  735.         jz      .dont_flip_vert
  736.  
  737.         imul    eax, ecx
  738.         sub     eax, [scanline_len]
  739.         shr     ecx, 1
  740.         mov     esi, [ebx + Image.Data]
  741.         lea     edi, [esi + eax]
  742.        
  743.   .next_line_vert:
  744.         push    ecx
  745.  
  746.         mov     ecx, [scanline_len]
  747.         push    ecx
  748.         shr     ecx, 2
  749.     @@: mov     eax, [esi]
  750.         xchg    eax, [edi]
  751.         mov     [esi], eax
  752.         add     esi, 4
  753.         add     edi, 4
  754.         sub     ecx, 1
  755.         jnz     @b
  756.         pop     ecx
  757.         and     ecx, 3
  758.         jz      .cont_line_vert
  759.     @@:
  760.         mov     al, [esi]
  761.         xchg    al, [edi]
  762.         mov     [esi], al
  763.         add     esi, 1
  764.         add     edi, 1
  765.         dec     ecx
  766.         jnz     @b
  767.     .cont_line_vert:
  768.  
  769.         pop     ecx
  770.         mov     eax, [scanline_len]
  771.         shl     eax, 1
  772.         sub     edi, eax
  773.         dec     ecx
  774.         jnz     .next_line_vert
  775.  
  776.   .dont_flip_vert:
  777.  
  778.         test    [_flip_kind], FLIP_HORIZONTAL
  779.         jz      .exit
  780.  
  781.         mov     ecx, [ebx + Image.Height]
  782.         mov     eax, [ebx + Image.Type]
  783.         mov     esi, [ebx + Image.Data]
  784.         mov     edi, [scanline_len]
  785.         add     edi, esi
  786.         jmp     dword [.handlers_horz + (eax-1)*4]
  787.  
  788. .bpp32_horz:
  789.         sub     edi, 4
  790.  
  791.   .next_line_horz:
  792.         push    ecx esi edi
  793.  
  794.         mov     ecx, [scanline_len]
  795.         shr     ecx, 3
  796.     @@: mov     eax, [esi]
  797.         xchg    eax, [edi]
  798.         mov     [esi], eax
  799.         add     esi, 4
  800.         add     edi, -4
  801.         sub     ecx, 1
  802.         jnz     @b
  803.  
  804.         pop     edi esi ecx
  805.         add     esi, [scanline_len]
  806.         add     edi, [scanline_len]
  807.         dec     ecx
  808.         jnz     .next_line_horz
  809.         jmp     .exit
  810.  
  811. .bpp1x_horz:
  812.         sub     edi, 2
  813.   .next_line_horz1x:
  814.         push    ecx esi edi
  815.  
  816.         mov     ecx, [ebx + Image.Width]
  817.     @@: mov     ax, [esi]
  818.         mov     dx, [edi]
  819.         mov     [edi], ax
  820.         mov     [esi], dx
  821.         add     esi, 2
  822.         sub     edi, 2
  823.         sub     ecx, 2
  824.         ja      @b
  825.  
  826.         pop     edi esi ecx
  827.         add     esi, [scanline_len]
  828.         add     edi, [scanline_len]
  829.         dec     ecx
  830.         jnz     .next_line_horz1x
  831.         jmp     .exit
  832.  
  833. .bpp8_horz:
  834.         dec     edi
  835.   .next_line_horz8:
  836.         push    ecx esi edi
  837.  
  838.         mov     ecx, [scanline_len]
  839.         shr     ecx, 1
  840.     @@: mov     al, [esi]
  841.         mov     dl, [edi]
  842.         mov     [edi], al
  843.         mov     [esi], dl
  844.         add     esi, 1
  845.         sub     edi, 1
  846.         sub     ecx, 1
  847.         jnz     @b
  848.  
  849.         pop     edi esi ecx
  850.         add     esi, [scanline_len]
  851.         add     edi, [scanline_len]
  852.         dec     ecx
  853.         jnz     .next_line_horz8
  854.         jmp     .exit
  855.  
  856. .bpp24_horz:
  857.         sub     edi, 3
  858.   .next_line_horz24:
  859.         push    ecx esi edi
  860.  
  861.         mov     ecx, [ebx + Image.Width]
  862.     @@:
  863.         mov     al, [esi]
  864.         mov     dl, [edi]
  865.         mov     [edi], al
  866.         mov     [esi], dl
  867.         mov     al, [esi+1]
  868.         mov     dl, [edi+1]
  869.         mov     [edi+1], al
  870.         mov     [esi+1], dl
  871.         mov     al, [esi+2]
  872.         mov     dl, [edi+2]
  873.         mov     [edi+2], al
  874.         mov     [esi+2], dl
  875.         add     esi, 3
  876.         sub     edi, 3
  877.         sub     ecx, 2
  878.         ja      @b
  879.  
  880.         pop     edi esi ecx
  881.         add     esi, [scanline_len]
  882.         add     edi, [scanline_len]
  883.         dec     ecx
  884.         jnz     .next_line_horz24
  885.  
  886.   .exit:
  887.         xor     eax, eax
  888.         inc     eax
  889.         pop     edi esi ebx
  890.         ret
  891.  
  892.   .error:
  893.         xor     eax, eax
  894.         pop     edi esi ebx
  895.         ret
  896. endp
  897.  
  898. ;;================================================================================================;;
  899. proc img.flip _img, _flip_kind ;//////////////////////////////////////////////////////////////////;;
  900. ;;------------------------------------------------------------------------------------------------;;
  901. ;? Flip all layers of image                                                                       ;;
  902. ;;------------------------------------------------------------------------------------------------;;
  903. ;> _img = pointer to image                                                                        ;;
  904. ;> _flip_kind = one of FLIP_* constants                                                           ;;
  905. ;;------------------------------------------------------------------------------------------------;;
  906. ;< eax = false / true                                                                             ;;
  907. ;;================================================================================================;;
  908.         push    1
  909.         mov     ebx, [_img]
  910. @@:
  911.         mov     eax, [ebx + Image.Previous]
  912.         test    eax, eax
  913.         jz      .loop
  914.         mov     ebx, eax
  915.         jmp     @b
  916. .loop:
  917.         stdcall img.flip.layer, ebx, [_flip_kind]
  918.         test    eax, eax
  919.         jnz     @f
  920.         mov     byte [esp], 0
  921. @@:
  922.         mov     ebx, [ebx + Image.Next]
  923.         test    ebx, ebx
  924.         jnz     .loop
  925.         pop     eax
  926.         ret
  927. endp
  928.  
  929. ;;================================================================================================;;
  930. proc img.rotate.layer _img, _rotate_kind ;////////////////////////////////////////////////////////;;
  931. ;;------------------------------------------------------------------------------------------------;;
  932. ;? Rotate image layer                                                                             ;;
  933. ;;------------------------------------------------------------------------------------------------;;
  934. ;> _img = pointer to image                                                                        ;;
  935. ;> _rotate_kind = one of ROTATE_* constants                                                       ;;
  936. ;;------------------------------------------------------------------------------------------------;;
  937. ;< eax = false / true                                                                             ;;
  938. ;;================================================================================================;;
  939. locals
  940.   scanline_len_old    dd ?
  941.   scanline_len_new    dd ?
  942.   scanline_pixels_new dd ?
  943.   line_buffer         dd ?
  944.   pixels_ptr          dd ?
  945. endl
  946.  
  947.         mov     [line_buffer], 0
  948.  
  949.         push    ebx esi edi
  950.         mov     ebx, [_img]
  951.         stdcall img._.validate, ebx
  952.         or      eax, eax
  953.         jnz     .error
  954.  
  955.         cmp     [_rotate_kind], ROTATE_90_CCW
  956.         je      .rotate_ccw_low
  957.         cmp     [_rotate_kind], ROTATE_90_CW
  958.         je      .rotate_cw_low
  959.         cmp     [_rotate_kind], ROTATE_180
  960.         je      .flip
  961.         jmp     .exit
  962.  
  963.   .rotate_ccw_low:
  964.         mov     eax, [ebx + Image.Height]
  965.         mov     [scanline_pixels_new], eax
  966.         call    img._.get_scanline_len
  967.         mov     [scanline_len_new], eax
  968.  
  969.         invoke  mem.alloc, eax
  970.         or      eax, eax
  971.         jz      .error
  972.         mov     [line_buffer], eax
  973.  
  974.         mov     eax, [ebx + Image.Width]
  975.         mov     ecx, eax
  976.         call    img._.get_scanline_len
  977.         mov     [scanline_len_old], eax
  978.  
  979.         mov     eax, [scanline_len_new]
  980.         imul    eax, ecx
  981.         add     eax, [ebx + Image.Data]
  982.         mov     [pixels_ptr], eax
  983.  
  984.         cmp     [ebx + Image.Type], Image.bpp8
  985.         jz      .rotate_ccw8
  986.         cmp     [ebx + Image.Type], Image.bpp24
  987.         jz      .rotate_ccw24
  988.         cmp     [ebx + Image.Type], Image.bpp32
  989.         jz      .rotate_ccw32
  990.  
  991.   .next_column_ccw_low1x:
  992.         dec     ecx
  993.         js      .exchange_dims
  994.         push    ecx
  995.  
  996.         mov     edx, [scanline_len_old]
  997.         add     [scanline_len_old], -2
  998.  
  999.         mov     ecx, [scanline_pixels_new]
  1000.         mov     esi, [ebx + Image.Data]
  1001.         mov     edi, [line_buffer]
  1002.     @@: mov     ax, [esi]
  1003.         mov     [edi], ax
  1004.         add     esi, edx
  1005.         add     edi, 2
  1006.         sub     ecx, 1
  1007.         jnz     @b
  1008.  
  1009.         mov     eax, [scanline_pixels_new]
  1010.         mov     edi, [ebx + Image.Data]
  1011.         lea     esi, [edi + 2]
  1012.         mov     edx, [scanline_len_old]
  1013.     @@: mov     ecx, edx
  1014.         shr     ecx, 2
  1015.         rep     movsd
  1016.         mov     ecx, edx
  1017.         and     ecx, 3
  1018.         rep     movsb
  1019.         add     esi, 1
  1020.         sub     eax, 1
  1021.         jnz     @b
  1022.  
  1023.         mov     eax, [scanline_len_new]
  1024.         sub     [pixels_ptr], eax
  1025.         mov     ecx, [scanline_pixels_new]
  1026.         mov     esi, [line_buffer]
  1027.         mov     edi, [pixels_ptr]
  1028.         mov     edx, ecx
  1029.         shr     ecx, 2
  1030.         rep     movsd
  1031.         mov     ecx, edx
  1032.         and     ecx, 3
  1033.         rep     movsb
  1034.  
  1035.         pop     ecx
  1036.         jmp     .next_column_ccw_low1x
  1037.  
  1038. .rotate_ccw32:
  1039.   .next_column_ccw_low:
  1040.         dec     ecx
  1041.         js      .exchange_dims
  1042.         push    ecx
  1043.  
  1044.         mov     edx, [scanline_len_old]
  1045.         add     [scanline_len_old], -4
  1046.  
  1047.         mov     ecx, [scanline_pixels_new]
  1048.         mov     esi, [ebx + Image.Data]
  1049.         mov     edi, [line_buffer]
  1050.     @@: mov     eax, [esi]
  1051.         stosd
  1052.         add     esi, edx
  1053.         dec     ecx
  1054.         jnz     @b
  1055.  
  1056.         mov     eax, [scanline_pixels_new]
  1057.         mov     edi, [ebx + Image.Data]
  1058.         lea     esi, [edi + 4]
  1059.         mov     edx, [scanline_len_old]
  1060.         shr     edx, 2
  1061.     @@: mov     ecx, edx
  1062.         rep     movsd
  1063.         add     esi, 4
  1064.         dec     eax
  1065.         jnz     @b
  1066.  
  1067.         mov     eax, [scanline_len_new]
  1068.         sub     [pixels_ptr], eax
  1069.         mov     ecx, [scanline_pixels_new]
  1070.         mov     esi, [line_buffer]
  1071.         mov     edi, [pixels_ptr]
  1072.         rep     movsd
  1073.  
  1074.         pop     ecx
  1075.         jmp     .next_column_ccw_low
  1076.  
  1077. .rotate_ccw8:
  1078.   .next_column_ccw_low8:
  1079.         dec     ecx
  1080.         js      .exchange_dims
  1081.         push    ecx
  1082.  
  1083.         mov     edx, [scanline_len_old]
  1084.         add     [scanline_len_old], -1
  1085.  
  1086.         mov     ecx, [scanline_pixels_new]
  1087.         mov     esi, [ebx + Image.Data]
  1088.         mov     edi, [line_buffer]
  1089.     @@: mov     al, [esi]
  1090.         mov     [edi], al
  1091.         add     esi, edx
  1092.         add     edi, 1
  1093.         sub     ecx, 1
  1094.         jnz     @b
  1095.  
  1096.         mov     eax, [scanline_pixels_new]
  1097.         mov     edi, [ebx + Image.Data]
  1098.         lea     esi, [edi + 1]
  1099.         mov     edx, [scanline_len_old]
  1100.     @@: mov     ecx, edx
  1101.         shr     ecx, 2
  1102.         rep     movsd
  1103.         mov     ecx, edx
  1104.         and     ecx, 3
  1105.         rep     movsb
  1106.         add     esi, 1
  1107.         sub     eax, 1
  1108.         jnz     @b
  1109.  
  1110.         mov     eax, [scanline_len_new]
  1111.         sub     [pixels_ptr], eax
  1112.         mov     ecx, [scanline_pixels_new]
  1113.         mov     esi, [line_buffer]
  1114.         mov     edi, [pixels_ptr]
  1115.         mov     edx, ecx
  1116.         shr     ecx, 2
  1117.         rep     movsd
  1118.         mov     ecx, edx
  1119.         and     ecx, 3
  1120.         rep     movsb
  1121.  
  1122.         pop     ecx
  1123.         jmp     .next_column_ccw_low8
  1124.  
  1125. .rotate_ccw24:
  1126.   .next_column_ccw_low24:
  1127.         dec     ecx
  1128.         js      .exchange_dims
  1129.         push    ecx
  1130.  
  1131.         mov     edx, [scanline_len_old]
  1132.         add     [scanline_len_old], -3
  1133.  
  1134.         mov     ecx, [scanline_pixels_new]
  1135.         mov     esi, [ebx + Image.Data]
  1136.         mov     edi, [line_buffer]
  1137.     @@: mov     al, [esi]
  1138.         mov     [edi], al
  1139.         mov     al, [esi+1]
  1140.         mov     [edi+1], al
  1141.         mov     al, [esi+2]
  1142.         mov     [edi+2], al
  1143.         add     esi, edx
  1144.         add     edi, 3
  1145.         sub     ecx, 1
  1146.         jnz     @b
  1147.  
  1148.         mov     eax, [scanline_pixels_new]
  1149.         mov     edi, [ebx + Image.Data]
  1150.         lea     esi, [edi + 3]
  1151.         mov     edx, [scanline_len_old]
  1152.     @@: mov     ecx, edx
  1153.         shr     ecx, 2
  1154.         rep     movsd
  1155.         mov     ecx, edx
  1156.         and     ecx, 3
  1157.         rep     movsb
  1158.         add     esi, 3
  1159.         sub     eax, 1
  1160.         jnz     @b
  1161.  
  1162.         mov     eax, [scanline_len_new]
  1163.         sub     [pixels_ptr], eax
  1164.         mov     ecx, eax
  1165.         mov     esi, [line_buffer]
  1166.         mov     edi, [pixels_ptr]
  1167.         shr     ecx, 2
  1168.         rep     movsd
  1169.         mov     ecx, eax
  1170.         and     ecx, 3
  1171.         rep     movsb
  1172.  
  1173.         pop     ecx
  1174.         jmp     .next_column_ccw_low24
  1175.  
  1176.   .rotate_cw_low:
  1177.         mov     eax, [ebx + Image.Height]
  1178.         mov     [scanline_pixels_new], eax
  1179.         call    img._.get_scanline_len
  1180.         mov     [scanline_len_new], eax
  1181.  
  1182.         invoke  mem.alloc, eax
  1183.         or      eax, eax
  1184.         jz      .error
  1185.         mov     [line_buffer], eax
  1186.  
  1187.         mov     eax, [ebx + Image.Width]
  1188.         mov     ecx, eax
  1189.         call    img._.get_scanline_len
  1190.         mov     [scanline_len_old], eax
  1191.  
  1192.         mov     eax, [scanline_len_new]
  1193.         imul    eax, ecx
  1194.         add     eax, [ebx + Image.Data]
  1195.         mov     [pixels_ptr], eax
  1196.  
  1197.         cmp     [ebx + Image.Type], Image.bpp8
  1198.         jz      .rotate_cw8
  1199.         cmp     [ebx + Image.Type], Image.bpp24
  1200.         jz      .rotate_cw24
  1201.         cmp     [ebx + Image.Type], Image.bpp32
  1202.         jz      .rotate_cw32
  1203.  
  1204.   .next_column_cw_low1x:
  1205.         dec     ecx
  1206.         js      .exchange_dims
  1207.         push    ecx
  1208.  
  1209.         mov     edx, [scanline_len_old]
  1210.         add     [scanline_len_old], -2
  1211.  
  1212.         mov     ecx, [scanline_pixels_new]
  1213.         mov     esi, [pixels_ptr]
  1214.         add     esi, -2
  1215.         mov     edi, [line_buffer]
  1216.     @@: mov     ax, [esi]
  1217.         mov     [edi], ax
  1218.         sub     esi, edx
  1219.         add     edi, 2
  1220.         sub     ecx, 1
  1221.         jnz     @b
  1222.  
  1223.         mov     eax, [scanline_pixels_new]
  1224.         dec     eax
  1225.         mov     edi, [ebx + Image.Data]
  1226.         add     edi, [scanline_len_old]
  1227.         lea     esi, [edi + 2]
  1228.         mov     edx, [scanline_len_old]
  1229.     @@: mov     ecx, edx
  1230.         shr     ecx, 2
  1231.         rep     movsd
  1232.         mov     ecx, edx
  1233.         and     ecx, 3
  1234.         rep     movsb
  1235.         add     esi, 3
  1236.         sub     eax, 1
  1237.         jnz     @b
  1238.  
  1239.         mov     eax, [scanline_len_new]
  1240.         sub     [pixels_ptr], eax
  1241.         mov     ecx, eax
  1242.         mov     esi, [line_buffer]
  1243.         mov     edi, [pixels_ptr]
  1244.         shr     ecx, 2
  1245.         rep     movsd
  1246.         mov     ecx, eax
  1247.         and     ecx, 3
  1248.         rep     movsb
  1249.  
  1250.         pop     ecx
  1251.         jmp     .next_column_cw_low1x
  1252.  
  1253. .rotate_cw32:
  1254.   .next_column_cw_low:
  1255.         dec     ecx
  1256.         js      .exchange_dims
  1257.         push    ecx
  1258.  
  1259.         mov     edx, [scanline_len_old]
  1260.         add     [scanline_len_old], -4
  1261.  
  1262.         mov     ecx, [scanline_pixels_new]
  1263.         mov     esi, [pixels_ptr]
  1264.         add     esi, -4
  1265.         mov     edi, [line_buffer]
  1266.     @@: mov     eax, [esi]
  1267.         stosd
  1268.         sub     esi, edx
  1269.         dec     ecx
  1270.         jnz     @b
  1271.  
  1272.         mov     eax, [scanline_pixels_new]
  1273.         dec     eax
  1274.         mov     edi, [ebx + Image.Data]
  1275.         add     edi, [scanline_len_old]
  1276.         lea     esi, [edi + 4]
  1277.         mov     edx, [scanline_len_old]
  1278.         shr     edx, 2
  1279.     @@: mov     ecx, edx
  1280.         rep     movsd
  1281.         add     esi, 4
  1282.         dec     eax
  1283.         jnz     @b
  1284.  
  1285.         mov     eax, [scanline_len_new]
  1286.         sub     [pixels_ptr], eax
  1287.         mov     ecx, [scanline_pixels_new]
  1288.         mov     esi, [line_buffer]
  1289.         mov     edi, [pixels_ptr]
  1290.         rep     movsd
  1291.  
  1292.         pop     ecx
  1293.         jmp     .next_column_cw_low
  1294.  
  1295. .rotate_cw8:
  1296.   .next_column_cw_low8:
  1297.         dec     ecx
  1298.         js      .exchange_dims
  1299.         push    ecx
  1300.  
  1301.         mov     edx, [scanline_len_old]
  1302.         add     [scanline_len_old], -1
  1303.  
  1304.         mov     ecx, [scanline_pixels_new]
  1305.         mov     esi, [pixels_ptr]
  1306.         add     esi, -1
  1307.         mov     edi, [line_buffer]
  1308.     @@: mov     al, [esi]
  1309.         mov     [edi], al
  1310.         sub     esi, edx
  1311.         add     edi, 1
  1312.         sub     ecx, 1
  1313.         jnz     @b
  1314.  
  1315.         mov     eax, [scanline_pixels_new]
  1316.         dec     eax
  1317.         mov     edi, [ebx + Image.Data]
  1318.         add     edi, [scanline_len_old]
  1319.         lea     esi, [edi + 1]
  1320.         mov     edx, [scanline_len_old]
  1321.     @@: mov     ecx, edx
  1322.         shr     ecx, 2
  1323.         rep     movsd
  1324.         mov     ecx, edx
  1325.         and     ecx, 3
  1326.         rep     movsb
  1327.         add     esi, 1
  1328.         sub     eax, 1
  1329.         jnz     @b
  1330.  
  1331.         mov     eax, [scanline_len_new]
  1332.         sub     [pixels_ptr], eax
  1333.         mov     ecx, eax
  1334.         mov     esi, [line_buffer]
  1335.         mov     edi, [pixels_ptr]
  1336.         shr     ecx, 2
  1337.         rep     movsd
  1338.         mov     ecx, eax
  1339.         and     ecx, 3
  1340.         rep     movsb
  1341.  
  1342.         pop     ecx
  1343.         jmp     .next_column_cw_low8
  1344.  
  1345. .rotate_cw24:
  1346.   .next_column_cw_low24:
  1347.         dec     ecx
  1348.         js      .exchange_dims
  1349.         push    ecx
  1350.  
  1351.         mov     edx, [scanline_len_old]
  1352.         add     [scanline_len_old], -3
  1353.  
  1354.         mov     ecx, [scanline_pixels_new]
  1355.         mov     esi, [pixels_ptr]
  1356.         add     esi, -3
  1357.         mov     edi, [line_buffer]
  1358.     @@: mov     al, [esi]
  1359.         mov     [edi], al
  1360.         mov     al, [esi+1]
  1361.         mov     [edi+1], al
  1362.         mov     al, [esi+2]
  1363.         mov     [edi+2], al
  1364.         sub     esi, edx
  1365.         add     edi, 3
  1366.         sub     ecx, 1
  1367.         jnz     @b
  1368.  
  1369.         mov     eax, [scanline_pixels_new]
  1370.         dec     eax
  1371.         mov     edi, [ebx + Image.Data]
  1372.         add     edi, [scanline_len_old]
  1373.         lea     esi, [edi + 3]
  1374.         mov     edx, [scanline_len_old]
  1375.     @@: mov     ecx, edx
  1376.         shr     ecx, 2
  1377.         rep     movsd
  1378.         mov     ecx, edx
  1379.         and     ecx, 3
  1380.         rep     movsb
  1381.         add     esi, 3
  1382.         sub     eax, 1
  1383.         jnz     @b
  1384.  
  1385.         mov     eax, [scanline_len_new]
  1386.         sub     [pixels_ptr], eax
  1387.         mov     ecx, eax
  1388.         mov     esi, [line_buffer]
  1389.         mov     edi, [pixels_ptr]
  1390.         shr     ecx, 2
  1391.         rep     movsd
  1392.         mov     ecx, eax
  1393.         and     ecx, 3
  1394.         rep     movsb
  1395.  
  1396.         pop     ecx
  1397.         jmp     .next_column_cw_low24
  1398.  
  1399.   .flip:
  1400.         jmp     .exit
  1401.  
  1402.   .exchange_dims:
  1403.         push    [ebx + Image.Width] [ebx + Image.Height]
  1404.         pop     [ebx + Image.Width] [ebx + Image.Height]
  1405.  
  1406.   .exit:
  1407.         invoke  mem.free, [line_buffer]
  1408.         xor     eax, eax
  1409.         inc     eax
  1410.         pop     edi esi ebx
  1411.         ret
  1412.  
  1413.   .error:
  1414.         invoke  mem.free, [line_buffer]
  1415.         xor     eax, eax
  1416.         pop     edi esi ebx
  1417.         ret
  1418. endp
  1419.  
  1420. ;;================================================================================================;;
  1421. proc img.rotate _img, _rotate_kind ;//////////////////////////////////////////////////////////////;;
  1422. ;;------------------------------------------------------------------------------------------------;;
  1423. ;? Rotate all layers of image                                                                     ;;
  1424. ;;------------------------------------------------------------------------------------------------;;
  1425. ;> _img = pointer to image                                                                        ;;
  1426. ;> _rotate_kind = one of ROTATE_* constants                                                       ;;
  1427. ;;------------------------------------------------------------------------------------------------;;
  1428. ;< eax = false / true                                                                             ;;
  1429. ;;================================================================================================;;
  1430.         push    1
  1431.         mov     ebx, [_img]
  1432. @@:
  1433.         mov     eax, [ebx + Image.Previous]
  1434.         test    eax, eax
  1435.         jz      .loop
  1436.         mov     ebx, eax
  1437.         jmp     @b
  1438. .loop:
  1439.         stdcall img.rotate.layer, ebx, [_rotate_kind]
  1440.         test    eax, eax
  1441.         jnz     @f
  1442.         mov     byte [esp], 0
  1443. @@:
  1444.         mov     ebx, [ebx + Image.Next]
  1445.         test    ebx, ebx
  1446.         jnz     .loop
  1447.         pop     eax
  1448.         ret
  1449. endp
  1450.  
  1451. ;;================================================================================================;;
  1452. proc img.draw _img, _x, _y, _width, _height, _xpos, _ypos ;///////////////////////////////////////;;
  1453. ;;------------------------------------------------------------------------------------------------;;
  1454. ;? Draw image in the window                                                                       ;;
  1455. ;;------------------------------------------------------------------------------------------------;;
  1456. ;> _img = pointer to image                                                                        ;;
  1457. ;>_x = x-coordinate in the window                                                                 ;;
  1458. ;>_y = y-coordinate in the window                                                                 ;;
  1459. ;>_width = maximum width to draw                                                                  ;;
  1460. ;>_height = maximum height to draw                                                                ;;
  1461. ;>_xpos = offset in image by x-axis                                                               ;;
  1462. ;>_ypos = offset in image by y-axis                                                               ;;
  1463. ;;------------------------------------------------------------------------------------------------;;
  1464. ;< no return value                                                                                ;;
  1465. ;;================================================================================================;;
  1466.         push    ebx esi edi
  1467.         mov     ebx, [_img]
  1468.         stdcall img._.validate, ebx
  1469.         test    eax, eax
  1470.         jnz     .done
  1471.         mov     ecx, [ebx + Image.Width]
  1472.         sub     ecx, [_xpos]
  1473.         jbe     .done
  1474.         cmp     ecx, [_width]
  1475.         jb      @f
  1476.         mov     ecx, [_width]
  1477. @@:
  1478.         mov     edx, [ebx + Image.Height]
  1479.         sub     edx, [_ypos]
  1480.         jbe     .done
  1481.         cmp     edx, [_height]
  1482.         jb      @f
  1483.         mov     edx, [_height]
  1484. @@:
  1485.         mov     eax, [ebx + Image.Width]
  1486.         sub     eax, ecx
  1487.         call    img._.get_scanline_len
  1488.         shl     ecx, 16
  1489.         add     ecx, edx
  1490.         mov     edx, [_x - 2]
  1491.         mov     dx, word [_y]
  1492.         mov     esi, [ebx + Image.Type]
  1493.         mov     esi, [type2bpp + (esi-1)*4]
  1494.         mov     edi, [ebx + Image.Palette]
  1495.         mov     ebx, [ebx + Image.Data]
  1496.         push    ebp
  1497.         push    65
  1498.         pop     ebp
  1499.         xchg    eax, ebp
  1500.         int     40h
  1501.         pop     ebp
  1502. .done:
  1503.         pop     edi esi ebx
  1504.         ret
  1505. endp
  1506.  
  1507. ;;================================================================================================;;
  1508. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1509. ;;================================================================================================;;
  1510. ;! Below are private procs you should never call directly from your code                          ;;
  1511. ;;================================================================================================;;
  1512. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1513. ;;================================================================================================;;
  1514.  
  1515.  
  1516. ;;================================================================================================;;
  1517. proc img._.validate, _img ;///////////////////////////////////////////////////////////////////////;;
  1518. ;;------------------------------------------------------------------------------------------------;;
  1519. ;? --- TBD ---                                                                                    ;;
  1520. ;;------------------------------------------------------------------------------------------------;;
  1521. ;> --- TBD ---                                                                                    ;;
  1522. ;;------------------------------------------------------------------------------------------------;;
  1523. ;< --- TBD ---                                                                                    ;;
  1524. ;;================================================================================================;;
  1525.         xor     eax, eax
  1526.         ret
  1527. endp
  1528.  
  1529. ;;================================================================================================;;
  1530. proc img._.new ;//////////////////////////////////////////////////////////////////////////////////;;
  1531. ;;------------------------------------------------------------------------------------------------;;
  1532. ;? --- TBD ---                                                                                    ;;
  1533. ;;------------------------------------------------------------------------------------------------;;
  1534. ;> --- TBD ---                                                                                    ;;
  1535. ;;------------------------------------------------------------------------------------------------;;
  1536. ;< eax = 0 / pointer to image                                                                     ;;
  1537. ;;================================================================================================;;
  1538.         invoke  mem.alloc, sizeof.Image
  1539.         test    eax, eax
  1540.         jz      @f
  1541.         push    ecx
  1542.         xor     ecx, ecx
  1543.         mov     [eax + Image.Data], ecx
  1544.         mov     [eax + Image.Type], ecx
  1545.         mov     [eax + Image.Flags], ecx
  1546.         mov     [eax + Image.Extended], ecx
  1547.         mov     [eax + Image.Previous], ecx
  1548.         mov     [eax + Image.Next], ecx
  1549.         pop     ecx
  1550. @@:
  1551.         ret
  1552. endp
  1553.  
  1554. ;;================================================================================================;;
  1555. proc img._.delete _img ;//////////////////////////////////////////////////////////////////////////;;
  1556. ;;------------------------------------------------------------------------------------------------;;
  1557. ;? --- TBD ---                                                                                    ;;
  1558. ;;------------------------------------------------------------------------------------------------;;
  1559. ;> --- TBD ---                                                                                    ;;
  1560. ;;------------------------------------------------------------------------------------------------;;
  1561. ;< eax = false / true                                                                             ;;
  1562. ;;================================================================================================;;
  1563.         push    edx
  1564.         mov     edx, [_img]
  1565.         cmp     [edx + Image.Data], 0
  1566.         je      @f
  1567.         invoke  mem.free, [edx + Image.Data]
  1568.     @@: cmp     [edx + Image.Extended], 0
  1569.         je      @f
  1570.         invoke  mem.free, [edx + Image.Extended]
  1571.     @@: invoke  mem.free, edx
  1572.         pop     edx
  1573.         ret
  1574. endp
  1575.  
  1576. ;;================================================================================================;;
  1577. proc img._.resize_data _img, _width, _height ;////////////////////////////////////////////////////;;
  1578. ;;------------------------------------------------------------------------------------------------;;
  1579. ;? --- TBD ---                                                                                    ;;
  1580. ;;------------------------------------------------------------------------------------------------;;
  1581. ;> --- TBD ---                                                                                    ;;
  1582. ;;------------------------------------------------------------------------------------------------;;
  1583. ;< --- TBD ---                                                                                    ;;
  1584. ;;================================================================================================;;
  1585.         push    ebx esi
  1586.         mov     ebx, [_img]
  1587.         mov     eax, [_height]
  1588. ; our memory is limited, [_width]*[_height] must not overflow
  1589. ; image with width or height greater than 65535 is most likely bogus
  1590.         cmp     word [_width+2], 0
  1591.         jnz     .error
  1592.         cmp     word [_height+2], 0
  1593.         jnz     .error
  1594.         imul    eax, [_width]
  1595.         test    eax, eax
  1596.         jz      .error
  1597. ; do not allow images which require too many memory
  1598.         cmp     eax, 4000000h
  1599.         jae     .error
  1600.         cmp     [ebx + Image.Type], Image.bpp8
  1601.         jz      .bpp8
  1602.         cmp     [ebx + Image.Type], Image.bpp24
  1603.         jz      .bpp24
  1604. .bpp32:
  1605.         shl     eax, 2
  1606.         jmp     @f
  1607. .bpp24:
  1608.         lea     eax, [eax*3]
  1609.         jmp     @f
  1610. .bpp8:
  1611.         add     eax, 256*4      ; for palette
  1612. @@:
  1613.         mov     esi, eax
  1614.         invoke  mem.realloc, [ebx + Image.Data], eax
  1615.         or      eax, eax
  1616.         jz      .error
  1617.  
  1618.         mov     [ebx + Image.Data], eax
  1619.         push    [_width]
  1620.         pop     [ebx + Image.Width]
  1621.         push    [_height]
  1622.         pop     [ebx + Image.Height]
  1623.         cmp     [ebx + Image.Type], Image.bpp8
  1624.         jnz     .ret
  1625.         lea     esi, [eax + esi - 256*4]
  1626.         mov     [ebx + Image.Palette], esi
  1627.         jmp     .ret
  1628.  
  1629.   .error:
  1630.         xor     eax, eax
  1631.   .ret:
  1632.         pop     esi ebx
  1633.         ret
  1634. endp
  1635.  
  1636. ;;================================================================================================;;
  1637. img._.get_scanline_len: ;/////////////////////////////////////////////////////////////////////////;;
  1638. ;;------------------------------------------------------------------------------------------------;;
  1639. ;? --- TBD ---                                                                                    ;;
  1640. ;;------------------------------------------------------------------------------------------------;;
  1641. ;> --- TBD ---                                                                                    ;;
  1642. ;;------------------------------------------------------------------------------------------------;;
  1643. ;< --- TBD ---                                                                                    ;;
  1644. ;;================================================================================================;;
  1645.         cmp     [ebx + Image.Type], Image.bpp8
  1646.         jz      .bpp8.1
  1647.         cmp     [ebx + Image.Type], Image.bpp24
  1648.         jz      .bpp24.1
  1649.         add     eax, eax
  1650.         cmp     [ebx + Image.Type], Image.bpp32
  1651.         jnz     @f
  1652.         add     eax, eax
  1653.         jmp     @f
  1654. .bpp24.1:
  1655.         lea     eax, [eax*3]
  1656. .bpp8.1:
  1657. @@:
  1658.         ret
  1659.  
  1660.  
  1661. ;;================================================================================================;;
  1662. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1663. ;;================================================================================================;;
  1664. ;! Below is private data you should never use directly from your code                             ;;
  1665. ;;================================================================================================;;
  1666. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1667. ;;================================================================================================;;
  1668.  
  1669. align 4
  1670. img._.formats_table:
  1671.   .bmp dd img.is.bmp, img.decode.bmp, img.encode.bmp
  1672.   .ico dd img.is.ico, img.decode.ico_cur, img.encode.ico
  1673.   .cur dd img.is.cur, img.decode.ico_cur, img.encode.cur
  1674.   .gif dd img.is.gif, img.decode.gif, img.encode.gif
  1675.   .png dd img.is.png, img.decode.png, img.encode.png
  1676.   .jpg dd img.is.jpg, img.decode.jpg, img.encode.jpg
  1677.   .tga dd img.is.tga, img.decode.tga, img.encode.tga
  1678.   .z80 dd img.is.z80, img.decode.z80, img.encode.z80 ;this must be the last entry as there are no
  1679.   ;signatures in z80 screens at all
  1680.        dd 0
  1681.  
  1682. align 4
  1683. type2bpp        dd      8, 24, 32, 15, 16
  1684. img._.do_rgb.handlers:
  1685.         dd      img._.do_rgb.bpp8
  1686.         dd      img._.do_rgb.bpp24
  1687.         dd      img._.do_rgb.bpp32
  1688.         dd      img._.do_rgb.bpp15.amd  ; can be overwritten in lib_init
  1689.         dd      img._.do_rgb.bpp16.amd  ; can be overwritten in lib_init
  1690.  
  1691. img.flip.layer.handlers_horz:
  1692.         dd      img.flip.layer.bpp8_horz
  1693.         dd      img.flip.layer.bpp24_horz
  1694.         dd      img.flip.layer.bpp32_horz
  1695.         dd      img.flip.layer.bpp1x_horz
  1696.         dd      img.flip.layer.bpp1x_horz
  1697.  
  1698. ;;================================================================================================;;
  1699. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1700. ;;================================================================================================;;
  1701. ;! Exported functions section                                                                     ;;
  1702. ;;================================================================================================;;
  1703. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1704. ;;================================================================================================;;
  1705.  
  1706.  
  1707. align 4
  1708. @EXPORT:
  1709.  
  1710. export                                        \
  1711.         lib_init        , 'lib_init'        , \
  1712.         0x00050005      , 'version'         , \
  1713.         img.is_img      , 'img_is_img'      , \
  1714.         img.info        , 'img_info'        , \
  1715.         img.from_file   , 'img_from_file'   , \
  1716.         img.to_file     , 'img_to_file'     , \
  1717.         img.from_rgb    , 'img_from_rgb'    , \
  1718.         img.to_rgb      , 'img_to_rgb'      , \
  1719.         img.to_rgb2     , 'img_to_rgb2'     , \
  1720.         img.decode      , 'img_decode'      , \
  1721.         img.encode      , 'img_encode'      , \
  1722.         img.create      , 'img_create'      , \
  1723.         img.destroy     , 'img_destroy'     , \
  1724.         img.destroy.layer, 'img_destroy_layer', \
  1725.         img.count       , 'img_count'       , \
  1726.         img.lock_bits   , 'img_lock_bits'   , \
  1727.         img.unlock_bits , 'img_unlock_bits' , \
  1728.         img.flip        , 'img_flip'        , \
  1729.         img.flip.layer  , 'img_flip_layer'  , \
  1730.         img.rotate      , 'img_rotate'      , \
  1731.         img.rotate.layer, 'img_rotate_layer', \
  1732.         img.draw        , 'img_draw'
  1733.  
  1734. ; import from deflate unpacker
  1735. ; is initialized only when PNG loading is requested
  1736. align 4
  1737. @IMPORT:
  1738.  
  1739. library archiver, 'archiver.obj'
  1740. import  archiver, \
  1741.         deflate_unpack2, 'deflate_unpack2'
  1742.  
  1743. align 4
  1744. ; mutex for unpacker loading
  1745. deflate_loader_mutex    dd      0
  1746.  
  1747. ; default palette for GIF - b&w
  1748. gif_default_palette:
  1749.         db      0, 0, 0
  1750.         db      0xFF, 0xFF, 0xFF
  1751.  
  1752. section '.data' data readable writable align 16
  1753. ; uninitialized data - global constant tables
  1754. mem.alloc   dd ?
  1755. mem.free    dd ?
  1756. mem.realloc dd ?
  1757. dll.load    dd ?
  1758.  
  1759. ; data for YCbCr -> RGB translation
  1760. color_table_1           rd      256
  1761. color_table_2           rd      256
  1762. color_table_3           rd      256
  1763. color_table_4           rd      256
  1764.