Subversion Repositories Kolibri OS

Rev

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