Subversion Repositories Kolibri OS

Rev

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