Subversion Repositories Kolibri OS

Rev

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