Subversion Repositories Kolibri OS

Rev

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