Subversion Repositories Kolibri OS

Rev

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