Subversion Repositories Kolibri OS

Rev

Rev 1014 | Rev 1079 | 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.  
  39. mem.alloc   dd ?
  40. mem.free    dd ?
  41. mem.realloc dd ?
  42. dll.load    dd ?
  43.  
  44. ;;================================================================================================;;
  45. proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
  46. ;;------------------------------------------------------------------------------------------------;;
  47. ;? Library entry point (called after library load)                                                ;;
  48. ;;------------------------------------------------------------------------------------------------;;
  49. ;> eax = pointer to memory allocation routine                                                     ;;
  50. ;> ebx = pointer to memory freeing routine                                                        ;;
  51. ;> ecx = pointer to memory reallocation routine                                                   ;;
  52. ;> edx = pointer to library loading routine                                                       ;;
  53. ;;------------------------------------------------------------------------------------------------;;
  54. ;< eax = 1 (fail) / 0 (ok) (library initialization result)                                        ;;
  55. ;;================================================================================================;;
  56.         mov     [mem.alloc], eax
  57.         mov     [mem.free], ebx
  58.         mov     [mem.realloc], ecx
  59.         mov     [dll.load], edx
  60.  
  61.         call    img.initialize.jpeg
  62.  
  63.   .ok:  xor     eax,eax
  64.         ret
  65. endp
  66.  
  67. ;;================================================================================================;;
  68. proc img.is_img _data, _length ;//////////////////////////////////////////////////////////////////;;
  69. ;;------------------------------------------------------------------------------------------------;;
  70. ;? --- TBD ---                                                                                    ;;
  71. ;;------------------------------------------------------------------------------------------------;;
  72. ;> --- TBD ---                                                                                    ;;
  73. ;;------------------------------------------------------------------------------------------------;;
  74. ;< --- TBD ---                                                                                    ;;
  75. ;;================================================================================================;;
  76.         push    ebx
  77.         mov     ebx, img._.formats_table
  78.     @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
  79.         or      eax, eax
  80.         jnz     @f
  81.         add     ebx, sizeof.FormatsTableEntry
  82.         cmp     dword[ebx], 0
  83.         jnz     @b
  84.         xor     eax, eax
  85.     @@: pop     ebx
  86.         ret
  87. endp
  88.  
  89. ;;================================================================================================;;
  90. proc img.info _data, _length ;////////////////////////////////////////////////////////////////////;;
  91. ;;------------------------------------------------------------------------------------------------;;
  92. ;? --- TBD ---                                                                                    ;;
  93. ;;------------------------------------------------------------------------------------------------;;
  94. ;> --- TBD ---                                                                                    ;;
  95. ;;------------------------------------------------------------------------------------------------;;
  96. ;< --- TBD ---                                                                                    ;;
  97. ;;================================================================================================;;
  98.         xor     eax, eax
  99.         ret
  100. endp
  101.  
  102. ;;================================================================================================;;
  103. proc img.from_file _filename ;////////////////////////////////////////////////////////////////////;;
  104. ;;------------------------------------------------------------------------------------------------;;
  105. ;? --- TBD ---                                                                                    ;;
  106. ;;------------------------------------------------------------------------------------------------;;
  107. ;> --- TBD ---                                                                                    ;;
  108. ;;------------------------------------------------------------------------------------------------;;
  109. ;< eax = 0 / pointer to image                                                                     ;;
  110. ;;================================================================================================;;
  111.         xor     eax, eax
  112.         ret
  113. endp
  114.  
  115. ;;================================================================================================;;
  116. proc img.to_file _img, _filename ;////////////////////////////////////////////////////////////////;;
  117. ;;------------------------------------------------------------------------------------------------;;
  118. ;? --- TBD ---                                                                                    ;;
  119. ;;------------------------------------------------------------------------------------------------;;
  120. ;> --- TBD ---                                                                                    ;;
  121. ;;------------------------------------------------------------------------------------------------;;
  122. ;< eax = false / true                                                                             ;;
  123. ;;================================================================================================;;
  124.         xor     eax, eax
  125.         ret
  126. endp
  127.  
  128. ;;================================================================================================;;
  129. proc img.from_rgb _rgb_data ;/////////////////////////////////////////////////////////////////////;;
  130. ;;------------------------------------------------------------------------------------------------;;
  131. ;? --- TBD ---                                                                                    ;;
  132. ;;------------------------------------------------------------------------------------------------;;
  133. ;> --- TBD ---                                                                                    ;;
  134. ;;------------------------------------------------------------------------------------------------;;
  135. ;< eax = 0 / pointer to image                                                                     ;;
  136. ;;================================================================================================;;
  137.         xor     eax, eax
  138.         ret
  139. endp
  140.  
  141. ;;================================================================================================;;
  142. proc img.to_rgb2 _img, _out ;/////////////////////////////////////////////////////////////////////;;
  143. ;;------------------------------------------------------------------------------------------------;;
  144. ;? --- TBD ---                                                                                    ;;
  145. ;;------------------------------------------------------------------------------------------------;;
  146. ;> --- TBD ---                                                                                    ;;
  147. ;;------------------------------------------------------------------------------------------------;;
  148. ;< --- TBD ---                                                                                    ;;
  149. ;;================================================================================================;;
  150.         push    esi edi
  151.         mov     esi, [_img]
  152.         stdcall img._.validate, esi
  153.         or      eax, eax
  154.         jnz     .ret
  155.         mov     edi, [_out]
  156.         call    img._.do_rgb
  157. .ret:
  158.         pop     edi esi
  159.         ret
  160. endp
  161.  
  162. ;;================================================================================================;;
  163. proc img.to_rgb _img ;////////////////////////////////////////////////////////////////////////////;;
  164. ;;------------------------------------------------------------------------------------------------;;
  165. ;? --- TBD ---                                                                                    ;;
  166. ;;------------------------------------------------------------------------------------------------;;
  167. ;> --- TBD ---                                                                                    ;;
  168. ;;------------------------------------------------------------------------------------------------;;
  169. ;< eax = 0 / pointer to rgb_data (array of [rgb] triplets)                                        ;;
  170. ;;================================================================================================;;
  171.         push    esi edi
  172.         mov     esi, [_img]
  173.         stdcall img._.validate, esi
  174.         or      eax, eax
  175.         jnz     .error
  176.  
  177.         mov     esi, [_img]
  178.         mov     ecx, [esi + Image.Width]
  179.         imul    ecx, [esi + Image.Height]
  180.         lea     eax, [ecx * 3 + 4 * 3]
  181.         invoke  mem.alloc, eax
  182.         or      eax, eax
  183.         jz      .error
  184.  
  185.         mov     edi, eax
  186.         push    eax
  187.         mov     eax, [esi + Image.Width]
  188.         stosd
  189.         mov     eax, [esi + Image.Height]
  190.         stosd
  191.         call    img._.do_rgb
  192.         pop     eax
  193.         pop     edi esi
  194.         ret
  195.  
  196.   .error:
  197.         xor     eax, eax
  198.         pop     edi esi
  199.         ret
  200. endp
  201.  
  202. ;;================================================================================================;;
  203. proc img._.do_rgb ;///////////////////////////////////////////////////////////////////////////////;;
  204. ;;------------------------------------------------------------------------------------------------;;
  205. ;? --- TBD ---                                                                                    ;;
  206. ;;------------------------------------------------------------------------------------------------;;
  207. ;> --- TBD ---                                                                                    ;;
  208. ;;------------------------------------------------------------------------------------------------;;
  209. ;< --- TBD ---                                                                                    ;;
  210. ;;================================================================================================;;
  211.         mov     ecx, [esi + Image.Width]
  212.         imul    ecx, [esi + Image.Height]
  213.         mov     eax, [esi + Image.Type]
  214.         dec     eax
  215.         jz      .bpp8
  216.         dec     eax
  217.         jz      .bpp24
  218. ; 32 BPP -> 24 BPP
  219.         mov     esi, [esi + Image.Data]
  220.  
  221.     @@:
  222.         mov     eax, [esi]
  223.         mov     [edi], ax
  224.         shr     eax, 16
  225.         mov     [edi+2], al
  226.         add     esi, 4
  227.         add     edi, 3
  228.         sub     ecx, 1
  229.         jnz     @b
  230.  
  231.     @@:
  232.         ret
  233.  
  234. .bpp24:
  235. ; 24 BPP -> 24 BPP
  236.         lea     ecx, [ecx*3 + 3]
  237.         mov     esi, [esi + Image.Data]
  238.         shr     ecx, 2
  239.         rep     movsd
  240.         ret
  241.  
  242. .bpp8:
  243. ; 8 BPP -> 24 BPP
  244.         push    ebx
  245.         mov     ebx, [esi + Image.Palette]
  246.         mov     esi, [esi + Image.Data]
  247. @@:
  248.         movzx   eax, byte [esi]
  249.         add     esi, 1
  250.         mov     eax, [ebx + eax*4]
  251.         mov     [edi], ax
  252.         shr     eax, 16
  253.         mov     [edi+2], al
  254.         add     edi, 3
  255.         sub     ecx, 1
  256.         jnz     @b
  257.         pop     ebx
  258.         ret
  259. endp
  260.  
  261. ;;================================================================================================;;
  262. proc img.decode _data, _length ;//////////////////////////////////////////////////////////////////;;
  263. ;;------------------------------------------------------------------------------------------------;;
  264. ;? --- TBD ---                                                                                    ;;
  265. ;;------------------------------------------------------------------------------------------------;;
  266. ;> --- TBD ---                                                                                    ;;
  267. ;;------------------------------------------------------------------------------------------------;;
  268. ;< eax = 0 / pointer to image                                                                     ;;
  269. ;;================================================================================================;;
  270.         push    ebx
  271.         mov     ebx, img._.formats_table
  272.     @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
  273.         or      eax, eax
  274.         jnz     @f
  275.         add     ebx, sizeof.FormatsTableEntry
  276.         cmp     dword[ebx], 0
  277.         jnz     @b
  278.         jmp     .error
  279.     @@: stdcall [ebx + FormatsTableEntry.Decode], [_data], [_length]
  280.  
  281.   .error:
  282.         ret
  283. endp
  284.  
  285. ;;================================================================================================;;
  286. proc img.encode _img, _p_length ;/////////////////////////////////////////////////////////////////;;
  287. ;;------------------------------------------------------------------------------------------------;;
  288. ;? --- TBD ---                                                                                    ;;
  289. ;;------------------------------------------------------------------------------------------------;;
  290. ;> --- TBD ---                                                                                    ;;
  291. ;;------------------------------------------------------------------------------------------------;;
  292. ;< eax = 0 / pointer to encoded data                                                              ;;
  293. ;< [_p_length] = data length                                                                      ;;
  294. ;;================================================================================================;;
  295.         xor     eax, eax
  296.         ret
  297. endp
  298.  
  299. ;;================================================================================================;;
  300. proc img.create _width, _height, _type ;//////////////////////////////////////////////////////////;;
  301. ;;------------------------------------------------------------------------------------------------;;
  302. ;? --- TBD ---                                                                                    ;;
  303. ;;------------------------------------------------------------------------------------------------;;
  304. ;> --- TBD ---                                                                                    ;;
  305. ;;------------------------------------------------------------------------------------------------;;
  306. ;< eax = 0 / pointer to image                                                                     ;;
  307. ;;================================================================================================;;
  308.         push    ecx
  309.  
  310.         stdcall img._.new
  311.         or      eax, eax
  312.         jz      .error
  313.  
  314.         mov     ecx, [_type]
  315.         mov     [eax + Image.Type], ecx
  316.  
  317.         push    eax
  318.  
  319.         stdcall img._.resize_data, eax, [_width], [_height]
  320.         or      eax, eax
  321.         jz      .error.2
  322.  
  323.         pop     eax
  324.         jmp     .ret
  325.  
  326.   .error.2:
  327. ;       pop     eax
  328.         stdcall img._.delete; eax
  329.         xor     eax, eax
  330.  
  331.   .error:
  332.   .ret:
  333.         pop     ecx
  334.         ret
  335. endp
  336.  
  337. ;;================================================================================================;;
  338. proc img.destroy _img ;///////////////////////////////////////////////////////////////////////////;;
  339. ;;------------------------------------------------------------------------------------------------;;
  340. ;? --- TBD ---                                                                                    ;;
  341. ;;------------------------------------------------------------------------------------------------;;
  342. ;> --- TBD ---                                                                                    ;;
  343. ;;------------------------------------------------------------------------------------------------;;
  344. ;< eax = false / true                                                                             ;;
  345. ;;================================================================================================;;
  346.         ;TODO: link Next and Previous
  347.         stdcall img._.delete, [_img]
  348.         ret
  349. endp
  350.  
  351. ;;================================================================================================;;
  352. proc img.count _img ;/////////////////////////////////////////////////////////////////////////////;;
  353. ;;------------------------------------------------------------------------------------------------;;
  354. ;? Get number of images in the list (e.g. in animated GIF file)                                   ;;
  355. ;;------------------------------------------------------------------------------------------------;;
  356. ;> _img = pointer to image                                                                        ;;
  357. ;;------------------------------------------------------------------------------------------------;;
  358. ;< eax = -1 (fail) / >0 (ok)                                                                      ;;
  359. ;;================================================================================================;;
  360.         push    ecx edx
  361.         mov     edx, [_img]
  362.         stdcall img._.validate, edx
  363.         or      eax, eax
  364.         jnz     .error
  365.  
  366.     @@: mov     eax, [edx + Image.Previous]
  367.         or      eax, eax
  368.         jz      @f
  369.         mov     edx, eax
  370.         jmp     @b
  371.  
  372.     @@: xor     ecx, ecx
  373.     @@: inc     ecx
  374.         mov     eax, [edx + Image.Next]
  375.         or      eax, eax
  376.         jz      .exit
  377.         mov     edx, eax
  378.         jmp     @b
  379.  
  380.   .exit:
  381.         mov     eax, ecx
  382.         pop     edx ecx
  383.         ret
  384.  
  385.   .error:
  386.         or      eax, -1
  387.         pop     edx ecx
  388.         ret
  389. endp
  390.  
  391. ;;//// image processing //////////////////////////////////////////////////////////////////////////;;
  392.  
  393. ;;================================================================================================;;
  394. proc img.lock_bits _img, _start_line, _end_line ;/////////////////////////////////////////////////;;
  395. ;;------------------------------------------------------------------------------------------------;;
  396. ;? --- TBD ---                                                                                    ;;
  397. ;;------------------------------------------------------------------------------------------------;;
  398. ;> --- TBD ---                                                                                    ;;
  399. ;;------------------------------------------------------------------------------------------------;;
  400. ;< eax = 0 / pointer to bits                                                                      ;;
  401. ;;================================================================================================;;
  402.         xor     eax, eax
  403.         ret
  404. endp
  405.  
  406. ;;================================================================================================;;
  407. proc img.unlock_bits _img, _lock ;////////////////////////////////////////////////////////////////;;
  408. ;;------------------------------------------------------------------------------------------------;;
  409. ;? --- TBD ---                                                                                    ;;
  410. ;;------------------------------------------------------------------------------------------------;;
  411. ;> --- TBD ---                                                                                    ;;
  412. ;;------------------------------------------------------------------------------------------------;;
  413. ;< eax = false / true                                                                             ;;
  414. ;;================================================================================================;;
  415.         xor     eax, eax
  416.         ret
  417. endp
  418.  
  419. ;;================================================================================================;;
  420. proc img.flip _img, _flip_kind ;//////////////////////////////////////////////////////////////////;;
  421. ;;------------------------------------------------------------------------------------------------;;
  422. ;? Flip image                                                                                     ;;
  423. ;;------------------------------------------------------------------------------------------------;;
  424. ;> _img = pointer to image                                                                        ;;
  425. ;> _flip_kind = one of FLIP_* constants                                                           ;;
  426. ;;------------------------------------------------------------------------------------------------;;
  427. ;< eax = false / true                                                                             ;;
  428. ;;================================================================================================;;
  429. locals
  430.   scanline_len dd ?
  431. endl
  432.  
  433.         push    ebx esi edi
  434.         mov     ebx, [_img]
  435.         stdcall img._.validate, ebx
  436.         or      eax, eax
  437.         jnz     .error
  438.  
  439.         mov     ecx, [ebx + Image.Height]
  440.         mov     eax, [ebx + Image.Width]
  441.         call    img._.get_scanline_len
  442.         mov     [scanline_len], eax
  443.  
  444.         test    [_flip_kind], FLIP_VERTICAL
  445.         jz      .dont_flip_vert
  446.  
  447.         imul    eax, ecx
  448.         sub     eax, [scanline_len]
  449.         shr     ecx, 1
  450.         mov     esi, [ebx + Image.Data]
  451.         lea     edi, [esi + eax]
  452.        
  453.   .next_line_vert:
  454.         push    ecx
  455.  
  456.         mov     ecx, [scanline_len]
  457.         push    ecx
  458.         shr     ecx, 2
  459.     @@: mov     eax, [esi]
  460.         xchg    eax, [edi]
  461.         mov     [esi], eax
  462.         add     esi, 4
  463.         add     edi, 4
  464.         sub     ecx, 1
  465.         jnz     @b
  466.         pop     ecx
  467.         and     ecx, 3
  468.         jz      .cont_line_vert
  469.     @@:
  470.         mov     al, [esi]
  471.         xchg    al, [edi]
  472.         mov     [esi], al
  473.         add     esi, 1
  474.         add     edi, 1
  475.         dec     ecx
  476.         jnz     @b
  477.     .cont_line_vert:
  478.  
  479.         pop     ecx
  480.         mov     eax, [scanline_len]
  481.         shl     eax, 1
  482.         sub     edi, eax
  483.         dec     ecx
  484.         jnz     .next_line_vert
  485.  
  486.   .dont_flip_vert:
  487.  
  488.         test    [_flip_kind], FLIP_HORIZONTAL
  489.         jz      .exit
  490.  
  491.         mov     ecx, [ebx + Image.Height]
  492.         mov     eax, [ebx + Image.Type]
  493.         mov     esi, [ebx + Image.Data]
  494.         mov     edi, [scanline_len]
  495.         add     edi, esi
  496.  
  497.         dec     eax
  498.         jz      .bpp8.2
  499.         dec     eax
  500.         jz      .bpp24.2
  501.  
  502.         sub     edi, 4
  503.  
  504.   .next_line_horz:
  505.         push    ecx esi edi
  506.  
  507.         mov     ecx, [scanline_len]
  508.         shr     ecx, 3
  509.     @@: mov     eax, [esi]
  510.         xchg    eax, [edi]
  511.         mov     [esi], eax
  512.         add     esi, 4
  513.         add     edi, -4
  514.         sub     ecx, 1
  515.         jnz     @b
  516.  
  517.         pop     edi esi ecx
  518.         add     esi, [scanline_len]
  519.         add     edi, [scanline_len]
  520.         dec     ecx
  521.         jnz     .next_line_horz
  522.         jmp     .exit
  523.  
  524. .bpp8.2:
  525.         dec     edi
  526.   .next_line_horz8:
  527.         push    ecx esi edi
  528.  
  529.         mov     ecx, [scanline_len]
  530.         shr     ecx, 1
  531.     @@: mov     al, [esi]
  532.         mov     dl, [edi]
  533.         mov     [edi], al
  534.         mov     [esi], dl
  535.         add     esi, 1
  536.         sub     edi, 1
  537.         sub     ecx, 1
  538.         jnz     @b
  539.  
  540.         pop     edi esi ecx
  541.         add     esi, [scanline_len]
  542.         add     edi, [scanline_len]
  543.         dec     ecx
  544.         jnz     .next_line_horz8
  545.         jmp     .exit
  546.  
  547. .bpp24.2:
  548.         sub     edi, 3
  549.   .next_line_horz32:
  550.         push    ecx esi edi
  551.  
  552.         mov     ecx, [ebx + Image.Width]
  553.         shr     ecx, 1
  554.     @@:
  555.         mov     al, [esi]
  556.         mov     dl, [edi]
  557.         mov     [edi], al
  558.         mov     [esi], dl
  559.         mov     al, [esi+1]
  560.         mov     dl, [edi+1]
  561.         mov     [edi+1], al
  562.         mov     [esi+1], dl
  563.         mov     al, [esi+2]
  564.         mov     dl, [edi+2]
  565.         mov     [edi+2], al
  566.         mov     [esi+2], dl
  567.         add     esi, 3
  568.         sub     edi, 3
  569.         sub     ecx, 1
  570.         jnz     @b
  571.  
  572.         pop     edi esi ecx
  573.         add     esi, [scanline_len]
  574.         add     edi, [scanline_len]
  575.         dec     ecx
  576.         jnz     .next_line_horz32
  577.  
  578.   .exit:
  579.         xor     eax, eax
  580.         inc     eax
  581.         pop     edi esi ebx
  582.         ret
  583.  
  584.   .error:
  585.         xor     eax, eax
  586.         pop     edi esi ebx
  587.         ret
  588. endp
  589.  
  590. ;;================================================================================================;;
  591. proc img.rotate _img, _rotate_kind ;//////////////////////////////////////////////////////////////;;
  592. ;;------------------------------------------------------------------------------------------------;;
  593. ;? Rotate image                                                                                   ;;
  594. ;;------------------------------------------------------------------------------------------------;;
  595. ;> _img = pointer to image                                                                        ;;
  596. ;> _rotate_kind = one of ROTATE_* constants                                                       ;;
  597. ;;------------------------------------------------------------------------------------------------;;
  598. ;< eax = false / true                                                                             ;;
  599. ;;================================================================================================;;
  600. locals
  601.   scanline_len_old    dd ?
  602.   scanline_len_new    dd ?
  603.   scanline_pixels_new dd ?
  604.   line_buffer         dd ?
  605.   pixels_ptr          dd ?
  606. endl
  607.  
  608.         mov     [line_buffer], 0
  609.  
  610.         push    ebx esi edi
  611.         mov     ebx, [_img]
  612.         stdcall img._.validate, ebx
  613.         or      eax, eax
  614.         jnz     .error
  615.  
  616.         cmp     [_rotate_kind], ROTATE_90_CCW
  617.         je      .rotate_ccw_low
  618.         cmp     [_rotate_kind], ROTATE_90_CW
  619.         je      .rotate_cw_low
  620.         cmp     [_rotate_kind], ROTATE_180
  621.         je      .flip
  622.         jmp     .exit
  623.  
  624.   .rotate_ccw_low:
  625.         mov     eax, [ebx + Image.Height]
  626.         mov     [scanline_pixels_new], eax
  627.         call    img._.get_scanline_len
  628.         mov     [scanline_len_new], eax
  629.  
  630.         invoke  mem.alloc, eax
  631.         or      eax, eax
  632.         jz      .error
  633.         mov     [line_buffer], eax
  634.  
  635.         mov     eax, [ebx + Image.Width]
  636.         mov     ecx, eax
  637.         call    img._.get_scanline_len
  638.         mov     [scanline_len_old], eax
  639.  
  640.         mov     eax, [scanline_len_new]
  641.         imul    eax, ecx
  642.         add     eax, [ebx + Image.Data]
  643.         mov     [pixels_ptr], eax
  644.  
  645.         cmp     [ebx + Image.Type], Image.bpp8
  646.         jz      .rotate_ccw8
  647.         cmp     [ebx + Image.Type], Image.bpp24
  648.         jz      .rotate_ccw24
  649.  
  650.   .next_column_ccw_low:
  651.         dec     ecx
  652.         js      .exchange_dims
  653.         push    ecx
  654.  
  655.         mov     edx, [scanline_len_old]
  656.         add     [scanline_len_old], -4
  657.  
  658.         mov     ecx, [scanline_pixels_new]
  659.         mov     esi, [ebx + Image.Data]
  660.         mov     edi, [line_buffer]
  661.     @@: mov     eax, [esi]
  662.         stosd
  663.         add     esi, edx
  664.         dec     ecx
  665.         jnz     @b
  666.  
  667.         mov     eax, [scanline_pixels_new]
  668.         mov     edi, [ebx + Image.Data]
  669.         lea     esi, [edi + 4]
  670.         mov     edx, [scanline_len_old]
  671.         shr     edx, 2
  672.     @@: mov     ecx, edx
  673.         rep     movsd
  674.         add     esi, 4
  675.         dec     eax
  676.         jnz     @b
  677.  
  678.         mov     eax, [scanline_len_new]
  679.         sub     [pixels_ptr], eax
  680.         mov     ecx, [scanline_pixels_new]
  681.         mov     esi, [line_buffer]
  682.         mov     edi, [pixels_ptr]
  683.         rep     movsd
  684.  
  685.         pop     ecx
  686.         jmp     .next_column_ccw_low
  687.  
  688. .rotate_ccw8:
  689.   .next_column_ccw_low8:
  690.         dec     ecx
  691.         js      .exchange_dims
  692.         push    ecx
  693.  
  694.         mov     edx, [scanline_len_old]
  695.         add     [scanline_len_old], -1
  696.  
  697.         mov     ecx, [scanline_pixels_new]
  698.         mov     esi, [ebx + Image.Data]
  699.         mov     edi, [line_buffer]
  700.     @@: mov     al, [esi]
  701.         mov     [edi], al
  702.         add     esi, edx
  703.         add     edi, 1
  704.         sub     ecx, 1
  705.         jnz     @b
  706.  
  707.         mov     eax, [scanline_pixels_new]
  708.         mov     edi, [ebx + Image.Data]
  709.         lea     esi, [edi + 1]
  710.         mov     edx, [scanline_len_old]
  711.     @@: mov     ecx, edx
  712.         shr     ecx, 2
  713.         rep     movsd
  714.         mov     ecx, edx
  715.         and     ecx, 3
  716.         rep     movsb
  717.         add     esi, 1
  718.         sub     eax, 1
  719.         jnz     @b
  720.  
  721.         mov     eax, [scanline_len_new]
  722.         sub     [pixels_ptr], eax
  723.         mov     ecx, [scanline_pixels_new]
  724.         mov     esi, [line_buffer]
  725.         mov     edi, [pixels_ptr]
  726.         mov     edx, ecx
  727.         shr     ecx, 2
  728.         rep     movsd
  729.         mov     ecx, edx
  730.         and     ecx, 3
  731.         rep     movsb
  732.  
  733.         pop     ecx
  734.         jmp     .next_column_ccw_low8
  735.  
  736. .rotate_ccw24:
  737.   .next_column_ccw_low24:
  738.         dec     ecx
  739.         js      .exchange_dims
  740.         push    ecx
  741.  
  742.         mov     edx, [scanline_len_old]
  743.         add     [scanline_len_old], -3
  744.  
  745.         mov     ecx, [scanline_pixels_new]
  746.         mov     esi, [ebx + Image.Data]
  747.         mov     edi, [line_buffer]
  748.     @@: mov     al, [esi]
  749.         mov     [edi], al
  750.         mov     al, [esi+1]
  751.         mov     [edi+1], al
  752.         mov     al, [esi+2]
  753.         mov     [edi+2], al
  754.         add     esi, edx
  755.         add     edi, 3
  756.         sub     ecx, 1
  757.         jnz     @b
  758.  
  759.         mov     eax, [scanline_pixels_new]
  760.         mov     edi, [ebx + Image.Data]
  761.         lea     esi, [edi + 3]
  762.         mov     edx, [scanline_len_old]
  763.     @@: mov     ecx, edx
  764.         shr     ecx, 2
  765.         rep     movsd
  766.         mov     ecx, edx
  767.         and     ecx, 3
  768.         rep     movsb
  769.         add     esi, 3
  770.         sub     eax, 1
  771.         jnz     @b
  772.  
  773.         mov     eax, [scanline_len_new]
  774.         sub     [pixels_ptr], eax
  775.         mov     ecx, eax
  776.         mov     esi, [line_buffer]
  777.         mov     edi, [pixels_ptr]
  778.         shr     ecx, 2
  779.         rep     movsd
  780.         mov     ecx, eax
  781.         and     ecx, 3
  782.         rep     movsb
  783.  
  784.         pop     ecx
  785.         jmp     .next_column_ccw_low24
  786.  
  787.   .rotate_cw_low:
  788.         mov     eax, [ebx + Image.Height]
  789.         mov     [scanline_pixels_new], eax
  790.         call    img._.get_scanline_len
  791.         mov     [scanline_len_new], eax
  792.  
  793.         invoke  mem.alloc, eax
  794.         or      eax, eax
  795.         jz      .error
  796.         mov     [line_buffer], eax
  797.  
  798.         mov     eax, [ebx + Image.Width]
  799.         mov     ecx, eax
  800.         call    img._.get_scanline_len
  801.         mov     [scanline_len_old], eax
  802.  
  803.         mov     eax, [scanline_len_new]
  804.         imul    eax, ecx
  805.         add     eax, [ebx + Image.Data]
  806.         mov     [pixels_ptr], eax
  807.  
  808.         cmp     [ebx + Image.Type], Image.bpp8
  809.         jz      .rotate_cw8
  810.         cmp     [ebx + Image.Type], Image.bpp24
  811.         jz      .rotate_cw24
  812.  
  813.   .next_column_cw_low:
  814.         dec     ecx
  815.         js      .exchange_dims
  816.         push    ecx
  817.  
  818.         mov     edx, [scanline_len_old]
  819.         add     [scanline_len_old], -4
  820.  
  821.         mov     ecx, [scanline_pixels_new]
  822.         mov     esi, [pixels_ptr]
  823.         add     esi, -4
  824.         mov     edi, [line_buffer]
  825.     @@: mov     eax, [esi]
  826.         stosd
  827.         sub     esi, edx
  828.         dec     ecx
  829.         jnz     @b
  830.  
  831.         mov     eax, [scanline_pixels_new]
  832.         dec     eax
  833.         mov     edi, [ebx + Image.Data]
  834.         add     edi, [scanline_len_old]
  835.         lea     esi, [edi + 4]
  836.         mov     edx, [scanline_len_old]
  837.         shr     edx, 2
  838.     @@: mov     ecx, edx
  839.         rep     movsd
  840.         add     esi, 4
  841.         dec     eax
  842.         jnz     @b
  843.  
  844.         mov     eax, [scanline_len_new]
  845.         sub     [pixels_ptr], eax
  846.         mov     ecx, [scanline_pixels_new]
  847.         mov     esi, [line_buffer]
  848.         mov     edi, [pixels_ptr]
  849.         rep     movsd
  850.  
  851.         pop     ecx
  852.         jmp     .next_column_cw_low
  853.  
  854. .rotate_cw8:
  855.   .next_column_cw_low8:
  856.         dec     ecx
  857.         js      .exchange_dims
  858.         push    ecx
  859.  
  860.         mov     edx, [scanline_len_old]
  861.         add     [scanline_len_old], -1
  862.  
  863.         mov     ecx, [scanline_pixels_new]
  864.         mov     esi, [pixels_ptr]
  865.         add     esi, -1
  866.         mov     edi, [line_buffer]
  867.     @@: mov     al, [esi]
  868.         mov     [edi], al
  869.         sub     esi, edx
  870.         add     edi, 1
  871.         sub     ecx, 1
  872.         jnz     @b
  873.  
  874.         mov     eax, [scanline_pixels_new]
  875.         dec     eax
  876.         mov     edi, [ebx + Image.Data]
  877.         add     edi, [scanline_len_old]
  878.         lea     esi, [edi + 1]
  879.         mov     edx, [scanline_len_old]
  880.     @@: mov     ecx, edx
  881.         shr     ecx, 2
  882.         rep     movsd
  883.         mov     ecx, edx
  884.         and     ecx, 3
  885.         rep     movsb
  886.         add     esi, 1
  887.         sub     eax, 1
  888.         jnz     @b
  889.  
  890.         mov     eax, [scanline_len_new]
  891.         sub     [pixels_ptr], eax
  892.         mov     ecx, eax
  893.         mov     esi, [line_buffer]
  894.         mov     edi, [pixels_ptr]
  895.         shr     ecx, 2
  896.         rep     movsd
  897.         mov     ecx, eax
  898.         and     ecx, 3
  899.         rep     movsb
  900.  
  901.         pop     ecx
  902.         jmp     .next_column_cw_low8
  903.  
  904. .rotate_cw24:
  905.   .next_column_cw_low24:
  906.         dec     ecx
  907.         js      .exchange_dims
  908.         push    ecx
  909.  
  910.         mov     edx, [scanline_len_old]
  911.         add     [scanline_len_old], -3
  912.  
  913.         mov     ecx, [scanline_pixels_new]
  914.         mov     esi, [pixels_ptr]
  915.         add     esi, -3
  916.         mov     edi, [line_buffer]
  917.     @@: mov     al, [esi]
  918.         mov     [edi], al
  919.         mov     al, [esi+1]
  920.         mov     [edi+1], al
  921.         mov     al, [esi+2]
  922.         mov     [edi+2], al
  923.         sub     esi, edx
  924.         add     edi, 3
  925.         sub     ecx, 1
  926.         jnz     @b
  927.  
  928.         mov     eax, [scanline_pixels_new]
  929.         dec     eax
  930.         mov     edi, [ebx + Image.Data]
  931.         add     edi, [scanline_len_old]
  932.         lea     esi, [edi + 3]
  933.         mov     edx, [scanline_len_old]
  934.     @@: mov     ecx, edx
  935.         shr     ecx, 2
  936.         rep     movsd
  937.         mov     ecx, edx
  938.         and     ecx, 3
  939.         rep     movsb
  940.         add     esi, 3
  941.         sub     eax, 1
  942.         jnz     @b
  943.  
  944.         mov     eax, [scanline_len_new]
  945.         sub     [pixels_ptr], eax
  946.         mov     ecx, eax
  947.         mov     esi, [line_buffer]
  948.         mov     edi, [pixels_ptr]
  949.         shr     ecx, 2
  950.         rep     movsd
  951.         mov     ecx, eax
  952.         and     ecx, 3
  953.         rep     movsb
  954.  
  955.         pop     ecx
  956.         jmp     .next_column_cw_low24
  957.  
  958.   .flip:
  959.         jmp     .exit
  960.  
  961.   .exchange_dims:
  962.         push    [ebx + Image.Width] [ebx + Image.Height]
  963.         pop     [ebx + Image.Width] [ebx + Image.Height]
  964.  
  965.   .exit:
  966.         invoke  mem.free, [line_buffer]
  967.         xor     eax, eax
  968.         inc     eax
  969.         pop     edi esi ebx
  970.         ret
  971.  
  972.   .error:
  973.         invoke  mem.free, [line_buffer]
  974.         xor     eax, eax
  975.         pop     edi esi ebx
  976.         ret
  977. endp
  978.  
  979.  
  980. ;;================================================================================================;;
  981. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  982. ;;================================================================================================;;
  983. ;! Below are private procs you should never call directly from your code                          ;;
  984. ;;================================================================================================;;
  985. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  986. ;;================================================================================================;;
  987.  
  988.  
  989. ;;================================================================================================;;
  990. proc img._.validate, _img ;///////////////////////////////////////////////////////////////////////;;
  991. ;;------------------------------------------------------------------------------------------------;;
  992. ;? --- TBD ---                                                                                    ;;
  993. ;;------------------------------------------------------------------------------------------------;;
  994. ;> --- TBD ---                                                                                    ;;
  995. ;;------------------------------------------------------------------------------------------------;;
  996. ;< --- TBD ---                                                                                    ;;
  997. ;;================================================================================================;;
  998.         xor     eax, eax
  999.         ret
  1000. endp
  1001.  
  1002. ;;================================================================================================;;
  1003. proc img._.new ;//////////////////////////////////////////////////////////////////////////////////;;
  1004. ;;------------------------------------------------------------------------------------------------;;
  1005. ;? --- TBD ---                                                                                    ;;
  1006. ;;------------------------------------------------------------------------------------------------;;
  1007. ;> --- TBD ---                                                                                    ;;
  1008. ;;------------------------------------------------------------------------------------------------;;
  1009. ;< eax = 0 / pointer to image                                                                     ;;
  1010. ;;================================================================================================;;
  1011.         invoke  mem.alloc, sizeof.Image
  1012.         test    eax, eax
  1013.         jz      @f
  1014.         push    ecx
  1015.         xor     ecx, ecx
  1016.         mov     [eax + Image.Data], ecx
  1017.         mov     [eax + Image.Type], ecx
  1018.         mov     [eax + Image.Extended], ecx
  1019.         mov     [eax + Image.Previous], ecx
  1020.         mov     [eax + Image.Next], ecx
  1021.         pop     ecx
  1022. @@:
  1023.         ret
  1024. endp
  1025.  
  1026. ;;================================================================================================;;
  1027. proc img._.delete _img ;//////////////////////////////////////////////////////////////////////////;;
  1028. ;;------------------------------------------------------------------------------------------------;;
  1029. ;? --- TBD ---                                                                                    ;;
  1030. ;;------------------------------------------------------------------------------------------------;;
  1031. ;> --- TBD ---                                                                                    ;;
  1032. ;;------------------------------------------------------------------------------------------------;;
  1033. ;< eax = false / true                                                                             ;;
  1034. ;;================================================================================================;;
  1035.         push    edx
  1036.         mov     edx, [_img]
  1037.         cmp     [edx + Image.Data], 0
  1038.         je      @f
  1039.         invoke  mem.free, [edx + Image.Data]
  1040.     @@: cmp     [edx + Image.Extended], 0
  1041.         je      @f
  1042.         invoke  mem.free, [edx + Image.Extended]
  1043.     @@: invoke  mem.free, edx
  1044.         pop     edx
  1045.         ret
  1046. endp
  1047.  
  1048. ;;================================================================================================;;
  1049. proc img._.resize_data _img, _width, _height ;////////////////////////////////////////////////////;;
  1050. ;;------------------------------------------------------------------------------------------------;;
  1051. ;? --- TBD ---                                                                                    ;;
  1052. ;;------------------------------------------------------------------------------------------------;;
  1053. ;> --- TBD ---                                                                                    ;;
  1054. ;;------------------------------------------------------------------------------------------------;;
  1055. ;< --- TBD ---                                                                                    ;;
  1056. ;;================================================================================================;;
  1057.         push    ebx esi
  1058.         mov     ebx, [_img]
  1059.         mov     eax, [_height]
  1060. ; our memory is limited, [_width]*[_height] must not overflow
  1061. ; image with width or height greater than 65535 is most likely bogus
  1062.         cmp     word [_width+2], 0
  1063.         jnz     .error
  1064.         cmp     word [_height+2], 0
  1065.         jnz     .error
  1066.         imul    eax, [_width]
  1067.         test    eax, eax
  1068.         jz      .error
  1069. ; do not allow images which require too many memory
  1070.         cmp     eax, 4000000h
  1071.         jae     .error
  1072.         cmp     [ebx + Image.Type], Image.bpp8
  1073.         jz      .bpp8
  1074.         cmp     [ebx + Image.Type], Image.bpp24
  1075.         jz      .bpp24
  1076. .bpp32:
  1077.         shl     eax, 2
  1078.         jmp     @f
  1079. .bpp24:
  1080.         lea     eax, [eax*3]
  1081.         jmp     @f
  1082. .bpp8:
  1083.         add     eax, 256*4      ; for palette
  1084. @@:
  1085.         mov     esi, eax
  1086.         invoke  mem.realloc, [ebx + Image.Data], eax
  1087.         or      eax, eax
  1088.         jz      .error
  1089.  
  1090.         mov     [ebx + Image.Data], eax
  1091.         push    [_width]
  1092.         pop     [ebx + Image.Width]
  1093.         push    [_height]
  1094.         pop     [ebx + Image.Height]
  1095.         cmp     [ebx + Image.Type], Image.bpp8
  1096.         jnz     .ret
  1097.         lea     esi, [eax + esi - 256*4]
  1098.         mov     [ebx + Image.Palette], esi
  1099.         jmp     .ret
  1100.  
  1101.   .error:
  1102.         xor     eax, eax
  1103.   .ret:
  1104.         pop     esi ebx
  1105.         ret
  1106. endp
  1107.  
  1108. ;;================================================================================================;;
  1109. img._.get_scanline_len: ;/////////////////////////////////////////////////////////////////////////;;
  1110. ;;------------------------------------------------------------------------------------------------;;
  1111. ;? --- TBD ---                                                                                    ;;
  1112. ;;------------------------------------------------------------------------------------------------;;
  1113. ;> --- TBD ---                                                                                    ;;
  1114. ;;------------------------------------------------------------------------------------------------;;
  1115. ;< --- TBD ---                                                                                    ;;
  1116. ;;================================================================================================;;
  1117.         cmp     [ebx + Image.Type], Image.bpp8
  1118.         jz      .bpp8.1
  1119.         cmp     [ebx + Image.Type], Image.bpp24
  1120.         jz      .bpp24.1
  1121.         shl     eax, 2
  1122.         jmp     @f
  1123. .bpp24.1:
  1124.         lea     eax, [eax*3]
  1125. .bpp8.1:
  1126. @@:
  1127.         ret
  1128.  
  1129.  
  1130. ;;================================================================================================;;
  1131. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1132. ;;================================================================================================;;
  1133. ;! Below is private data you should never use directly from your code                             ;;
  1134. ;;================================================================================================;;
  1135. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1136. ;;================================================================================================;;
  1137.  
  1138.  
  1139. img._.formats_table:
  1140.   .bmp dd img.is.bmp, img.decode.bmp, img.encode.bmp
  1141. ; .ico dd img.is.ico, img.decode.ico, img.encode.ico
  1142. ; .cur dd img.is.cur, img.decode.cur, img.encode.cur
  1143.   .gif dd img.is.gif, img.decode.gif, img.encode.gif
  1144.   .png dd img.is.png, img.decode.png, img.encode.png
  1145.   .jpg dd img.is.jpg, img.decode.jpg, img.encode.jpg
  1146.        dd 0
  1147.  
  1148.  
  1149. ;;================================================================================================;;
  1150. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1151. ;;================================================================================================;;
  1152. ;! Exported functions section                                                                     ;;
  1153. ;;================================================================================================;;
  1154. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1155. ;;================================================================================================;;
  1156.  
  1157.  
  1158. align 4
  1159. @EXPORT:
  1160.  
  1161. export                                        \
  1162.         lib_init        , 'lib_init'        , \
  1163.         0x00010003      , 'version'         , \
  1164.         img.is_img      , 'img.is_img'      , \
  1165.         img.info        , 'img.info'        , \
  1166.         img.from_file   , 'img.from_file'   , \
  1167.         img.to_file     , 'img.to_file'     , \
  1168.         img.from_rgb    , 'img.from_rgb'    , \
  1169.         img.to_rgb      , 'img.to_rgb'      , \
  1170.         img.to_rgb2     , 'img.to_rgb2'     , \
  1171.         img.decode      , 'img.decode'      , \
  1172.         img.encode      , 'img.encode'      , \
  1173.         img.create      , 'img.create'      , \
  1174.         img.destroy     , 'img.destroy'     , \
  1175.         img.count       , 'img.count'       , \
  1176.         img.lock_bits   , 'img.lock_bits'   , \
  1177.         img.unlock_bits , 'img.unlock_bits' , \
  1178.         img.flip        , 'img.flip'        , \
  1179.         img.rotate      , 'img.rotate'
  1180.  
  1181. ; import from deflate unpacker
  1182. ; is initialized only when PNG loading is requested
  1183. align 4
  1184. @IMPORT:
  1185.  
  1186. library kfar_arc, '../File Managers/kfar_arc.obj'
  1187. import  kfar_arc, \
  1188.         deflate_unpack2, 'deflate_unpack2'
  1189.  
  1190. ; mutex for unpacker loading
  1191. deflate_loader_mutex    dd      0
  1192.  
  1193. section '.data' data readable writable align 16
  1194. ; uninitialized data - global constant tables
  1195.  
  1196. ; data for YCbCr -> RGB translation
  1197. color_table_1           rd      256
  1198. color_table_2           rd      256
  1199. color_table_3           rd      256
  1200. color_table_4           rd      256
  1201.