Subversion Repositories Kolibri OS

Rev

Rev 1252 | Rev 1593 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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