Subversion Repositories Kolibri OS

Rev

Rev 1569 | Rev 2388 | 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. align 16
  507. .bpp1:
  508.     push ebx edx
  509.     mov ebx, esi
  510.     mov esi, [ebx + Image.Data]
  511.     mov ecx, [ebx + Image.Height]
  512.   .bpp1.pre:
  513.     mov edx, [ebx + Image.Width]
  514.     mov eax, 7
  515.   .bpp1.begin:
  516.     push ecx esi
  517.     xor cx, cx
  518.     bt [esi], eax
  519.     setc cl
  520.     mov esi, [ebx + Image.Palette]
  521.      jcxz @f
  522.     add esi, 4
  523.   @@:
  524.     mov ecx, 3
  525.     cld
  526.     rep movsb
  527.     pop esi ecx
  528.     dec edx
  529.      jz .bpp1.end_line
  530.     dec eax
  531.      jns .bpp1.begin
  532.     mov eax, 7
  533.     inc esi
  534.      jmp .bpp1.begin
  535.  
  536.   .bpp1.end_line:
  537.     dec ecx
  538.      jz .bpp1.quit
  539.     inc esi
  540.      jmp .bpp1.pre
  541.  
  542.   .bpp1.quit:
  543.     pop edx ebx
  544.     ret
  545.  
  546. endp
  547.  
  548. ;;================================================================================================;;
  549. proc img.decode _data, _length, _options ;////////////////////////////////////////////////////////;;
  550. ;;------------------------------------------------------------------------------------------------;;
  551. ;? --- TBD ---                                                                                    ;;
  552. ;;------------------------------------------------------------------------------------------------;;
  553. ;> --- TBD ---                                                                                    ;;
  554. ;;------------------------------------------------------------------------------------------------;;
  555. ;< eax = 0 / pointer to image                                                                     ;;
  556. ;;================================================================================================;;
  557.     push    ebx
  558.     mov ebx, img._.formats_table
  559.     @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
  560.     or  eax, eax
  561.     jnz @f
  562.     add ebx, sizeof.FormatsTableEntry
  563.     cmp dword[ebx], eax ;0
  564.     jnz @b
  565.     pop ebx
  566.     ret
  567.     @@: mov eax, [ebx + FormatsTableEntry.Decode]
  568.     pop ebx
  569.     leave
  570.     jmp eax
  571. endp
  572.  
  573. ;;================================================================================================;;
  574. proc img.encode _img, _p_length, _options ;///////////////////////////////////////////////////////;;
  575. ;;------------------------------------------------------------------------------------------------;;
  576. ;? --- TBD ---                                                                                    ;;
  577. ;;------------------------------------------------------------------------------------------------;;
  578. ;> --- TBD ---                                                                                    ;;
  579. ;;------------------------------------------------------------------------------------------------;;
  580. ;< eax = 0 / pointer to encoded data                                                              ;;
  581. ;< [_p_length] = data length                                                                      ;;
  582. ;;================================================================================================;;
  583.     xor eax, eax
  584.     ret
  585. endp
  586.  
  587. ;;================================================================================================;;
  588. proc img.create _width, _height, _type ;//////////////////////////////////////////////////////////;;
  589. ;;------------------------------------------------------------------------------------------------;;
  590. ;? --- TBD ---                                                                                    ;;
  591. ;;------------------------------------------------------------------------------------------------;;
  592. ;> --- TBD ---                                                                                    ;;
  593. ;;------------------------------------------------------------------------------------------------;;
  594. ;< eax = 0 / pointer to image                                                                     ;;
  595. ;;================================================================================================;;
  596.     push    ecx
  597.  
  598.     stdcall img._.new
  599.     or  eax, eax
  600.     jz  .error
  601.  
  602.     mov ecx, [_type]
  603.     mov [eax + Image.Type], ecx
  604.  
  605.     push    eax
  606.  
  607.     stdcall img._.resize_data, eax, [_width], [_height]
  608.     or  eax, eax
  609.     jz  .error.2
  610.  
  611.     pop eax
  612.     jmp .ret
  613.  
  614.   .error.2:
  615. ;       pop     eax
  616.     stdcall img._.delete; eax
  617.     xor eax, eax
  618.  
  619.   .error:
  620.   .ret:
  621.     pop ecx
  622.     ret
  623. endp
  624.  
  625. ;;================================================================================================;;
  626. proc img.destroy.layer _img ;/////////////////////////////////////////////////////////////////////;;
  627. ;;------------------------------------------------------------------------------------------------;;
  628. ;? --- TBD ---                                                                                    ;;
  629. ;;------------------------------------------------------------------------------------------------;;
  630. ;> --- TBD ---                                                                                    ;;
  631. ;;------------------------------------------------------------------------------------------------;;
  632. ;< eax = false / true                                                                             ;;
  633. ;;================================================================================================;;
  634.     mov eax, [_img]
  635.     mov edx, [eax + Image.Previous]
  636.     test    edx, edx
  637.     jz  @f
  638.     push    [eax + Image.Next]
  639.     pop [edx + Image.Next]
  640. @@:
  641.     mov edx, [eax + Image.Next]
  642.     test    edx, edx
  643.     jz  @f
  644.     push    [eax + Image.Previous]
  645.     pop [edx + Image.Previous]
  646. @@:
  647.     stdcall img._.delete, eax
  648.     ret
  649. endp
  650.  
  651. ;;================================================================================================;;
  652. proc img.destroy _img ;///////////////////////////////////////////////////////////////////////////;;
  653. ;;------------------------------------------------------------------------------------------------;;
  654. ;? --- TBD ---                                                                                    ;;
  655. ;;------------------------------------------------------------------------------------------------;;
  656. ;> --- TBD ---                                                                                    ;;
  657. ;;------------------------------------------------------------------------------------------------;;
  658. ;< eax = false / true                                                                             ;;
  659. ;;================================================================================================;;
  660.     push    1
  661.     mov eax, [_img]
  662.     mov eax, [eax + Image.Previous]
  663. .destroy_prev_loop:
  664.     test    eax, eax
  665.     jz  .destroy_prev_done
  666.     pushd   [eax + Image.Previous]
  667.     stdcall img._.delete, eax
  668.     test    eax, eax
  669.     jnz @f
  670.     mov byte [esp+4], 0
  671. @@:
  672.     pop eax
  673.     jmp .destroy_prev_loop
  674. .destroy_prev_done:
  675.     mov eax, [_img]
  676. .destroy_next_loop:
  677.     pushd   [eax + Image.Next]
  678.     stdcall img._.delete, eax
  679.     test    eax, eax
  680.     jnz @f
  681.     mov byte [esp+4], 0
  682. @@:
  683.     pop eax
  684.     test    eax, eax
  685.     jnz .destroy_next_loop
  686.     pop eax
  687.     ret
  688. endp
  689.  
  690. ;;================================================================================================;;
  691. proc img.count _img ;/////////////////////////////////////////////////////////////////////////////;;
  692. ;;------------------------------------------------------------------------------------------------;;
  693. ;? Get number of images in the list (e.g. in animated GIF file)                                   ;;
  694. ;;------------------------------------------------------------------------------------------------;;
  695. ;> _img = pointer to image                                                                        ;;
  696. ;;------------------------------------------------------------------------------------------------;;
  697. ;< eax = -1 (fail) / >0 (ok)                                                                      ;;
  698. ;;================================================================================================;;
  699.     push    ecx edx
  700.     mov edx, [_img]
  701.     stdcall img._.validate, edx
  702.     or  eax, eax
  703.     jnz .error
  704.  
  705.     @@: mov eax, [edx + Image.Previous]
  706.     or  eax, eax
  707.     jz  @f
  708.     mov edx, eax
  709.     jmp @b
  710.  
  711.     @@: xor ecx, ecx
  712.     @@: inc ecx
  713.     mov eax, [edx + Image.Next]
  714.     or  eax, eax
  715.     jz  .exit
  716.     mov edx, eax
  717.     jmp @b
  718.  
  719.   .exit:
  720.     mov eax, ecx
  721.     pop edx ecx
  722.     ret
  723.  
  724.   .error:
  725.     or  eax, -1
  726.     pop edx ecx
  727.     ret
  728. endp
  729.  
  730. ;;//// image processing //////////////////////////////////////////////////////////////////////////;;
  731.  
  732. ;;================================================================================================;;
  733. proc img.lock_bits _img, _start_line, _end_line ;/////////////////////////////////////////////////;;
  734. ;;------------------------------------------------------------------------------------------------;;
  735. ;? --- TBD ---                                                                                    ;;
  736. ;;------------------------------------------------------------------------------------------------;;
  737. ;> --- TBD ---                                                                                    ;;
  738. ;;------------------------------------------------------------------------------------------------;;
  739. ;< eax = 0 / pointer to bits                                                                      ;;
  740. ;;================================================================================================;;
  741.     xor eax, eax
  742.     ret
  743. endp
  744.  
  745. ;;================================================================================================;;
  746. proc img.unlock_bits _img, _lock ;////////////////////////////////////////////////////////////////;;
  747. ;;------------------------------------------------------------------------------------------------;;
  748. ;? --- TBD ---                                                                                    ;;
  749. ;;------------------------------------------------------------------------------------------------;;
  750. ;> --- TBD ---                                                                                    ;;
  751. ;;------------------------------------------------------------------------------------------------;;
  752. ;< eax = false / true                                                                             ;;
  753. ;;================================================================================================;;
  754.     xor eax, eax
  755.     ret
  756. endp
  757.  
  758. ;;================================================================================================;;
  759. proc img.flip.layer _img, _flip_kind ;////////////////////////////////////////////////////////////;;
  760. ;;------------------------------------------------------------------------------------------------;;
  761. ;? Flip image layer                                                                               ;;
  762. ;;------------------------------------------------------------------------------------------------;;
  763. ;> _img = pointer to image                                                                        ;;
  764. ;> _flip_kind = one of FLIP_* constants                                                           ;;
  765. ;;------------------------------------------------------------------------------------------------;;
  766. ;< eax = false / true                                                                             ;;
  767. ;;================================================================================================;;
  768. locals
  769.   scanline_len dd ?
  770. endl
  771.  
  772.     push    ebx esi edi
  773.     mov ebx, [_img]
  774.     stdcall img._.validate, ebx
  775.     or  eax, eax
  776.     jnz .error
  777.  
  778.     mov ecx, [ebx + Image.Height]
  779.     mov eax, [ebx + Image.Width]
  780.     call    img._.get_scanline_len
  781.     mov [scanline_len], eax
  782.  
  783.     test    [_flip_kind], FLIP_VERTICAL
  784.     jz  .dont_flip_vert
  785.  
  786.     imul    eax, ecx
  787.     sub eax, [scanline_len]
  788.     shr ecx, 1
  789.     mov esi, [ebx + Image.Data]
  790.     lea edi, [esi + eax]
  791.    
  792.   .next_line_vert:
  793.     push    ecx
  794.  
  795.     mov ecx, [scanline_len]
  796.     push    ecx
  797.     shr ecx, 2
  798.     @@: mov eax, [esi]
  799.     xchg    eax, [edi]
  800.     mov [esi], eax
  801.     add esi, 4
  802.     add edi, 4
  803.     sub ecx, 1
  804.     jnz @b
  805.     pop ecx
  806.     and ecx, 3
  807.     jz  .cont_line_vert
  808.     @@:
  809.     mov al, [esi]
  810.     xchg    al, [edi]
  811.     mov [esi], al
  812.     add esi, 1
  813.     add edi, 1
  814.     dec ecx
  815.     jnz @b
  816.     .cont_line_vert:
  817.  
  818.     pop ecx
  819.     mov eax, [scanline_len]
  820.     shl eax, 1
  821.     sub edi, eax
  822.     dec ecx
  823.     jnz .next_line_vert
  824.  
  825.   .dont_flip_vert:
  826.  
  827.     test    [_flip_kind], FLIP_HORIZONTAL
  828.     jz  .exit
  829.  
  830.     mov ecx, [ebx + Image.Height]
  831.     mov eax, [ebx + Image.Type]
  832.     mov esi, [ebx + Image.Data]
  833.     mov edi, [scanline_len]
  834.     add edi, esi
  835.     jmp dword [.handlers_horz + (eax-1)*4]
  836.  
  837. .bpp32_horz:
  838.     sub edi, 4
  839.  
  840.   .next_line_horz:
  841.     push    ecx esi edi
  842.  
  843.     mov ecx, [scanline_len]
  844.     shr ecx, 3
  845.     @@: mov eax, [esi]
  846.     xchg    eax, [edi]
  847.     mov [esi], eax
  848.     add esi, 4
  849.     add edi, -4
  850.     sub ecx, 1
  851.     jnz @b
  852.  
  853.     pop edi esi ecx
  854.     add esi, [scanline_len]
  855.     add edi, [scanline_len]
  856.     dec ecx
  857.     jnz .next_line_horz
  858.     jmp .exit
  859.  
  860. .bpp1x_horz:
  861.     sub edi, 2
  862.   .next_line_horz1x:
  863.     push    ecx esi edi
  864.  
  865.     mov ecx, [ebx + Image.Width]
  866.     @@: mov ax, [esi]
  867.     mov dx, [edi]
  868.     mov [edi], ax
  869.     mov [esi], dx
  870.     add esi, 2
  871.     sub edi, 2
  872.     sub ecx, 2
  873.     ja  @b
  874.  
  875.     pop edi esi ecx
  876.     add esi, [scanline_len]
  877.     add edi, [scanline_len]
  878.     dec ecx
  879.     jnz .next_line_horz1x
  880.     jmp .exit
  881.  
  882. .bpp8_horz:
  883.     dec edi
  884.   .next_line_horz8:
  885.     push    ecx esi edi
  886.  
  887.     mov ecx, [scanline_len]
  888.     shr ecx, 1
  889.     @@: mov al, [esi]
  890.     mov dl, [edi]
  891.     mov [edi], al
  892.     mov [esi], dl
  893.     add esi, 1
  894.     sub edi, 1
  895.     sub ecx, 1
  896.     jnz @b
  897.  
  898.     pop edi esi ecx
  899.     add esi, [scanline_len]
  900.     add edi, [scanline_len]
  901.     dec ecx
  902.     jnz .next_line_horz8
  903.     jmp .exit
  904.  
  905. .bpp24_horz:
  906.     sub edi, 3
  907.   .next_line_horz24:
  908.     push    ecx esi edi
  909.  
  910.     mov ecx, [ebx + Image.Width]
  911.     @@:
  912.     mov al, [esi]
  913.     mov dl, [edi]
  914.     mov [edi], al
  915.     mov [esi], dl
  916.     mov al, [esi+1]
  917.     mov dl, [edi+1]
  918.     mov [edi+1], al
  919.     mov [esi+1], dl
  920.     mov al, [esi+2]
  921.     mov dl, [edi+2]
  922.     mov [edi+2], al
  923.     mov [esi+2], dl
  924.     add esi, 3
  925.     sub edi, 3
  926.     sub ecx, 2
  927.     ja  @b
  928.  
  929.     pop edi esi ecx
  930.     add esi, [scanline_len]
  931.     add edi, [scanline_len]
  932.     dec ecx
  933.     jnz .next_line_horz24
  934.     jmp .exit
  935.  
  936. .bpp1_horz:
  937.     push eax edx
  938.     mov edi, [scanline_len]
  939.     mov edx, [ebx+Image.Width]
  940.     and edx,  0x07
  941.     neg dl
  942.     add dl, 8
  943.     and dl, 0x07                                        ; clear if cl=8
  944. .bpp1_horz.begin:
  945.     push ebx ecx edx esi
  946.     mov eax, 7
  947.     add edi, esi
  948.     sub edi, 1
  949.     mov ebx, [ebx+Image.Width]
  950.     shr ebx, 1
  951. .bpp1_horz.flip_line:
  952.     xor ecx, ecx
  953.     bt  [esi], eax
  954.     setc cl
  955.     bt  [edi], edx
  956.      jc .bpp1_horz.one
  957.   .bpp1_horz.zero:
  958.     btr [esi], eax
  959.      jmp @f
  960.   .bpp1_horz.one:
  961.     bts [esi], eax
  962.   @@:
  963.      jecxz .bpp1_horz.reset
  964.   .bpp1_horz.set:
  965.     bts [edi], edx
  966.      jmp @f
  967.   .bpp1_horz.reset:
  968.     btr [edi], edx
  969.   @@:
  970.     inc edx
  971.     and edx, 0x07
  972.      jnz @f
  973.     dec edi
  974.   @@:
  975.     dec eax
  976.      jns @f
  977.     mov eax, 7
  978.     inc esi
  979.   @@:
  980.     dec ebx
  981.      jnz .bpp1_horz.flip_line
  982.  
  983.     pop esi edx ecx ebx
  984.     add esi, [scanline_len]
  985.     mov edi, [scanline_len]
  986.     dec ecx
  987.      jnz .bpp1_horz.begin
  988.     pop edx eax
  989.  
  990.   .exit:
  991.     xor eax, eax
  992.     inc eax
  993.     pop edi esi ebx
  994.     ret
  995.  
  996.   .error:
  997.     xor eax, eax
  998.     pop edi esi ebx
  999.     ret
  1000. endp
  1001.  
  1002. ;;================================================================================================;;
  1003. proc img.flip _img, _flip_kind ;//////////////////////////////////////////////////////////////////;;
  1004. ;;------------------------------------------------------------------------------------------------;;
  1005. ;? Flip all layers of image                                                                       ;;
  1006. ;;------------------------------------------------------------------------------------------------;;
  1007. ;> _img = pointer to image                                                                        ;;
  1008. ;> _flip_kind = one of FLIP_* constants                                                           ;;
  1009. ;;------------------------------------------------------------------------------------------------;;
  1010. ;< eax = false / true                                                                             ;;
  1011. ;;================================================================================================;;
  1012.     push    1
  1013.     mov ebx, [_img]
  1014. @@:
  1015.     mov eax, [ebx + Image.Previous]
  1016.     test    eax, eax
  1017.     jz  .loop
  1018.     mov ebx, eax
  1019.     jmp @b
  1020. .loop:
  1021.     stdcall img.flip.layer, ebx, [_flip_kind]
  1022.     test    eax, eax
  1023.     jnz @f
  1024.     mov byte [esp], 0
  1025. @@:
  1026.     mov ebx, [ebx + Image.Next]
  1027.     test    ebx, ebx
  1028.     jnz .loop
  1029.     pop eax
  1030.     ret
  1031. endp
  1032.  
  1033. ;;================================================================================================;;
  1034. proc img.rotate.layer _img, _rotate_kind ;////////////////////////////////////////////////////////;;
  1035. ;;------------------------------------------------------------------------------------------------;;
  1036. ;? Rotate image layer                                                                             ;;
  1037. ;;------------------------------------------------------------------------------------------------;;
  1038. ;> _img = pointer to image                                                                        ;;
  1039. ;> _rotate_kind = one of ROTATE_* constants                                                       ;;
  1040. ;;------------------------------------------------------------------------------------------------;;
  1041. ;< eax = false / true                                                                             ;;
  1042. ;;================================================================================================;;
  1043. locals
  1044.   scanline_len_old    dd ?
  1045.   scanline_len_new    dd ?
  1046.   scanline_pixels_new dd ?
  1047.   line_buffer         dd ?
  1048.   pixels_ptr          dd ?
  1049. endl
  1050.  
  1051.     mov [line_buffer], 0
  1052.  
  1053.     push    ebx esi edi
  1054.     mov ebx, [_img]
  1055.     stdcall img._.validate, ebx
  1056.     or  eax, eax
  1057.     jnz .error
  1058.  
  1059.     cmp [_rotate_kind], ROTATE_90_CCW
  1060.     je  .rotate_ccw_low
  1061.     cmp [_rotate_kind], ROTATE_90_CW
  1062.     je  .rotate_cw_low
  1063.     cmp [_rotate_kind], ROTATE_180
  1064.     je  .flip
  1065.     jmp .exit
  1066.  
  1067.   .rotate_ccw_low:
  1068.     mov eax, [ebx + Image.Height]
  1069.     mov [scanline_pixels_new], eax
  1070.     call    img._.get_scanline_len
  1071.     mov [scanline_len_new], eax
  1072.  
  1073.     invoke  mem.alloc, eax
  1074.     or  eax, eax
  1075.     jz  .error
  1076.     mov [line_buffer], eax
  1077.  
  1078.     mov eax, [ebx + Image.Width]
  1079.     mov ecx, eax
  1080.     call    img._.get_scanline_len
  1081.     mov [scanline_len_old], eax
  1082.  
  1083.     mov eax, [scanline_len_new]
  1084.     imul    eax, ecx
  1085.     add eax, [ebx + Image.Data]
  1086.     mov [pixels_ptr], eax
  1087.  
  1088.     cmp [ebx + Image.Type], Image.bpp1
  1089.     jz  .rotate_ccw1
  1090.     cmp [ebx + Image.Type], Image.bpp8
  1091.     jz  .rotate_ccw8
  1092.     cmp [ebx + Image.Type], Image.bpp24
  1093.     jz  .rotate_ccw24
  1094.     cmp [ebx + Image.Type], Image.bpp32
  1095.     jz  .rotate_ccw32
  1096.  
  1097.   .next_column_ccw_low1x:
  1098.     dec ecx
  1099.     js  .exchange_dims
  1100.     push    ecx
  1101.  
  1102.     mov edx, [scanline_len_old]
  1103.     add [scanline_len_old], -2
  1104.  
  1105.     mov ecx, [scanline_pixels_new]
  1106.     mov esi, [ebx + Image.Data]
  1107.     mov edi, [line_buffer]
  1108.     @@: mov ax, [esi]
  1109.     mov [edi], ax
  1110.     add esi, edx
  1111.     add edi, 2
  1112.     sub ecx, 1
  1113.     jnz @b
  1114.  
  1115.     mov eax, [scanline_pixels_new]
  1116.     mov edi, [ebx + Image.Data]
  1117.     lea esi, [edi + 2]
  1118.     mov edx, [scanline_len_old]
  1119.     @@: mov ecx, edx
  1120.     shr ecx, 2
  1121.     rep movsd
  1122.     mov ecx, edx
  1123.     and ecx, 3
  1124.     rep movsb
  1125.     add esi, 1
  1126.     sub eax, 1
  1127.     jnz @b
  1128.  
  1129.     mov eax, [scanline_len_new]
  1130.     sub [pixels_ptr], eax
  1131.     mov ecx, [scanline_pixels_new]
  1132.     mov esi, [line_buffer]
  1133.     mov edi, [pixels_ptr]
  1134.     mov edx, ecx
  1135.     shr ecx, 2
  1136.     rep movsd
  1137.     mov ecx, edx
  1138.     and ecx, 3
  1139.     rep movsb
  1140.  
  1141.     pop ecx
  1142.     jmp .next_column_ccw_low1x
  1143.  
  1144. .rotate_ccw32:
  1145.   .next_column_ccw_low:
  1146.     dec ecx
  1147.     js  .exchange_dims
  1148.     push    ecx
  1149.  
  1150.     mov edx, [scanline_len_old]
  1151.     add [scanline_len_old], -4
  1152.  
  1153.     mov ecx, [scanline_pixels_new]
  1154.     mov esi, [ebx + Image.Data]
  1155.     mov edi, [line_buffer]
  1156.     @@: mov eax, [esi]
  1157.     stosd
  1158.     add esi, edx
  1159.     dec ecx
  1160.     jnz @b
  1161.  
  1162.     mov eax, [scanline_pixels_new]
  1163.     mov edi, [ebx + Image.Data]
  1164.     lea esi, [edi + 4]
  1165.     mov edx, [scanline_len_old]
  1166.     shr edx, 2
  1167.     @@: mov ecx, edx
  1168.     rep movsd
  1169.     add esi, 4
  1170.     dec eax
  1171.     jnz @b
  1172.  
  1173.     mov eax, [scanline_len_new]
  1174.     sub [pixels_ptr], eax
  1175.     mov ecx, [scanline_pixels_new]
  1176.     mov esi, [line_buffer]
  1177.     mov edi, [pixels_ptr]
  1178.     rep movsd
  1179.  
  1180.     pop ecx
  1181.     jmp .next_column_ccw_low
  1182.  
  1183. .rotate_ccw8:
  1184.   .next_column_ccw_low8:
  1185.     dec ecx
  1186.     js  .exchange_dims
  1187.     push    ecx
  1188.  
  1189.     mov edx, [scanline_len_old]
  1190.     add [scanline_len_old], -1
  1191.  
  1192.     mov ecx, [scanline_pixels_new]
  1193.     mov esi, [ebx + Image.Data]
  1194.     mov edi, [line_buffer]
  1195.     @@: mov al, [esi]
  1196.     mov [edi], al
  1197.     add esi, edx
  1198.     add edi, 1
  1199.     sub ecx, 1
  1200.     jnz @b
  1201.  
  1202.     mov eax, [scanline_pixels_new]
  1203.     mov edi, [ebx + Image.Data]
  1204.     lea esi, [edi + 1]
  1205.     mov edx, [scanline_len_old]
  1206.     @@: mov ecx, edx
  1207.     shr ecx, 2
  1208.     rep movsd
  1209.     mov ecx, edx
  1210.     and ecx, 3
  1211.     rep movsb
  1212.     add esi, 1
  1213.     sub eax, 1
  1214.     jnz @b
  1215.  
  1216.     mov eax, [scanline_len_new]
  1217.     sub [pixels_ptr], eax
  1218.     mov ecx, [scanline_pixels_new]
  1219.     mov esi, [line_buffer]
  1220.     mov edi, [pixels_ptr]
  1221.     mov edx, ecx
  1222.     shr ecx, 2
  1223.     rep movsd
  1224.     mov ecx, edx
  1225.     and ecx, 3
  1226.     rep movsb
  1227.  
  1228.     pop ecx
  1229.     jmp .next_column_ccw_low8
  1230.  
  1231. .rotate_ccw24:
  1232.   .next_column_ccw_low24:
  1233.     dec ecx
  1234.     js  .exchange_dims
  1235.     push    ecx
  1236.  
  1237.     mov edx, [scanline_len_old]
  1238.     add [scanline_len_old], -3
  1239.  
  1240.     mov ecx, [scanline_pixels_new]
  1241.     mov esi, [ebx + Image.Data]
  1242.     mov edi, [line_buffer]
  1243.     @@: mov al, [esi]
  1244.     mov [edi], al
  1245.     mov al, [esi+1]
  1246.     mov [edi+1], al
  1247.     mov al, [esi+2]
  1248.     mov [edi+2], al
  1249.     add esi, edx
  1250.     add edi, 3
  1251.     sub ecx, 1
  1252.     jnz @b
  1253.  
  1254.     mov eax, [scanline_pixels_new]
  1255.     mov edi, [ebx + Image.Data]
  1256.     lea esi, [edi + 3]
  1257.     mov edx, [scanline_len_old]
  1258.     @@: mov ecx, edx
  1259.     shr ecx, 2
  1260.     rep movsd
  1261.     mov ecx, edx
  1262.     and ecx, 3
  1263.     rep movsb
  1264.     add esi, 3
  1265.     sub eax, 1
  1266.     jnz @b
  1267.  
  1268.     mov eax, [scanline_len_new]
  1269.     sub [pixels_ptr], eax
  1270.     mov ecx, eax
  1271.     mov esi, [line_buffer]
  1272.     mov edi, [pixels_ptr]
  1273.     shr ecx, 2
  1274.     rep movsd
  1275.     mov ecx, eax
  1276.     and ecx, 3
  1277.     rep movsb
  1278.  
  1279.     pop ecx
  1280.     jmp .next_column_ccw_low24
  1281.  
  1282. .rotate_ccw1:
  1283.     push ecx edx
  1284.  
  1285.     mov eax, [ebx+Image.Height]
  1286.     add eax, 7
  1287.     shr eax, 3
  1288.     mul word[ebx+Image.Width]
  1289.     shl eax, 16
  1290.     shrd eax, edx, 16
  1291.     push eax                                            ; save new data size
  1292.  
  1293.     invoke  mem.alloc, eax
  1294.     or  eax, eax
  1295.     jz  .error
  1296.     push eax                                            ; save pointer to new data
  1297.  
  1298.     mov ecx, [ebx+Image.Width]
  1299.     and ecx,  0x07
  1300.     neg cl
  1301.     add cl, 8
  1302.     and cl, 0x07                                        ; clear if cl=8
  1303.  
  1304.     mov esi, eax
  1305.     mov edi, [ebx+Image.Data]
  1306.     mov eax, 7
  1307.     mov edx, [scanline_len_old]
  1308.     dec edx
  1309.     add edi, edx
  1310.  
  1311.   .rotate_ccw1.begin:
  1312.     bt  [edi], ecx
  1313.      jc .rotate_ccw1.one
  1314.   .rotate_ccw1.zero:
  1315.     btr [esi], eax
  1316.      jmp @f
  1317.   .rotate_ccw1.one:
  1318.     bts [esi], eax
  1319.   @@:
  1320.     add edi, [scanline_len_old]
  1321.     dec [scanline_pixels_new]
  1322.      jz .rotate_ccw1.end_of_line
  1323.     dec eax
  1324.      jns .rotate_ccw1.begin
  1325.     mov eax, 7
  1326.     inc esi
  1327.      jmp .rotate_ccw1.begin
  1328.  
  1329.   .rotate_ccw1.end_of_line:
  1330.     inc esi
  1331.     mov eax, 7
  1332.     mov edi, [ebx+Image.Height]
  1333.     mov [scanline_pixels_new],  edi
  1334.     inc ecx
  1335.     and cl, 0x07
  1336.      jz @f
  1337.     mov edi, [ebx+Image.Data]
  1338.     add edi, edx
  1339.      jmp .rotate_ccw1.begin
  1340.   @@:
  1341.     dec edx
  1342.      js .rotate_ccw1.quit
  1343.     mov edi, [ebx+Image.Data]
  1344.     add edi, edx
  1345.      jmp .rotate_ccw1.begin
  1346.  
  1347.   .rotate_ccw1.quit:
  1348.     pop eax                                             ; get pointer to new data
  1349.     mov esi, eax
  1350.     mov edi, [ebx + Image.Data]
  1351.     pop ecx                                             ; get new data size
  1352.     rep movsb
  1353.  
  1354.     invoke  mem.free, eax
  1355.  
  1356.     pop edx ecx
  1357.      jmp .exchange_dims
  1358.  
  1359.   .rotate_cw_low:
  1360.     mov eax, [ebx + Image.Height]
  1361.     mov [scanline_pixels_new], eax
  1362.     call    img._.get_scanline_len
  1363.     mov [scanline_len_new], eax
  1364.  
  1365.     invoke  mem.alloc, eax
  1366.     or  eax, eax
  1367.     jz  .error
  1368.     mov [line_buffer], eax
  1369.  
  1370.     mov eax, [ebx + Image.Width]
  1371.     mov ecx, eax
  1372.     call    img._.get_scanline_len
  1373.     mov [scanline_len_old], eax
  1374.  
  1375.     mov eax, [scanline_len_new]
  1376.     imul    eax, ecx
  1377.     add eax, [ebx + Image.Data]
  1378.     mov [pixels_ptr], eax
  1379.  
  1380.     cmp [ebx + Image.Type], Image.bpp1
  1381.     jz  .rotate_cw1
  1382.     cmp [ebx + Image.Type], Image.bpp8
  1383.     jz  .rotate_cw8
  1384.     cmp [ebx + Image.Type], Image.bpp24
  1385.     jz  .rotate_cw24
  1386.     cmp [ebx + Image.Type], Image.bpp32
  1387.     jz  .rotate_cw32
  1388.  
  1389.   .next_column_cw_low1x:
  1390.     dec ecx
  1391.     js  .exchange_dims
  1392.     push    ecx
  1393.  
  1394.     mov edx, [scanline_len_old]
  1395.     add [scanline_len_old], -2
  1396.  
  1397.     mov ecx, [scanline_pixels_new]
  1398.     mov esi, [pixels_ptr]
  1399.     add esi, -2
  1400.     mov edi, [line_buffer]
  1401.     @@: mov ax, [esi]
  1402.     mov [edi], ax
  1403.     sub esi, edx
  1404.     add edi, 2
  1405.     sub ecx, 1
  1406.     jnz @b
  1407.  
  1408.     mov eax, [scanline_pixels_new]
  1409.     dec eax
  1410.     mov edi, [ebx + Image.Data]
  1411.     add edi, [scanline_len_old]
  1412.     lea esi, [edi + 2]
  1413.     mov edx, [scanline_len_old]
  1414.     @@: mov ecx, edx
  1415.     shr ecx, 2
  1416.     rep movsd
  1417.     mov ecx, edx
  1418.     and ecx, 3
  1419.     rep movsb
  1420.     add esi, 3
  1421.     sub eax, 1
  1422.     jnz @b
  1423.  
  1424.     mov eax, [scanline_len_new]
  1425.     sub [pixels_ptr], eax
  1426.     mov ecx, eax
  1427.     mov esi, [line_buffer]
  1428.     mov edi, [pixels_ptr]
  1429.     shr ecx, 2
  1430.     rep movsd
  1431.     mov ecx, eax
  1432.     and ecx, 3
  1433.     rep movsb
  1434.  
  1435.     pop ecx
  1436.     jmp .next_column_cw_low1x
  1437.  
  1438. .rotate_cw32:
  1439.   .next_column_cw_low:
  1440.     dec ecx
  1441.     js  .exchange_dims
  1442.     push    ecx
  1443.  
  1444.     mov edx, [scanline_len_old]
  1445.     add [scanline_len_old], -4
  1446.  
  1447.     mov ecx, [scanline_pixels_new]
  1448.     mov esi, [pixels_ptr]
  1449.     add esi, -4
  1450.     mov edi, [line_buffer]
  1451.     @@: mov eax, [esi]
  1452.     stosd
  1453.     sub esi, edx
  1454.     dec ecx
  1455.     jnz @b
  1456.  
  1457.     mov eax, [scanline_pixels_new]
  1458.     dec eax
  1459.     mov edi, [ebx + Image.Data]
  1460.     add edi, [scanline_len_old]
  1461.     lea esi, [edi + 4]
  1462.     mov edx, [scanline_len_old]
  1463.     shr edx, 2
  1464.     @@: mov ecx, edx
  1465.     rep movsd
  1466.     add esi, 4
  1467.     dec eax
  1468.     jnz @b
  1469.  
  1470.     mov eax, [scanline_len_new]
  1471.     sub [pixels_ptr], eax
  1472.     mov ecx, [scanline_pixels_new]
  1473.     mov esi, [line_buffer]
  1474.     mov edi, [pixels_ptr]
  1475.     rep movsd
  1476.  
  1477.     pop ecx
  1478.     jmp .next_column_cw_low
  1479.  
  1480. .rotate_cw8:
  1481.   .next_column_cw_low8:
  1482.     dec ecx
  1483.     js  .exchange_dims
  1484.     push    ecx
  1485.  
  1486.     mov edx, [scanline_len_old]
  1487.     add [scanline_len_old], -1
  1488.  
  1489.     mov ecx, [scanline_pixels_new]
  1490.     mov esi, [pixels_ptr]
  1491.     add esi, -1
  1492.     mov edi, [line_buffer]
  1493.     @@: mov al, [esi]
  1494.     mov [edi], al
  1495.     sub esi, edx
  1496.     add edi, 1
  1497.     sub ecx, 1
  1498.     jnz @b
  1499.  
  1500.     mov eax, [scanline_pixels_new]
  1501.     dec eax
  1502.     mov edi, [ebx + Image.Data]
  1503.     add edi, [scanline_len_old]
  1504.     lea esi, [edi + 1]
  1505.     mov edx, [scanline_len_old]
  1506.     @@: mov ecx, edx
  1507.     shr ecx, 2
  1508.     rep movsd
  1509.     mov ecx, edx
  1510.     and ecx, 3
  1511.     rep movsb
  1512.     add esi, 1
  1513.     sub eax, 1
  1514.     jnz @b
  1515.  
  1516.     mov eax, [scanline_len_new]
  1517.     sub [pixels_ptr], eax
  1518.     mov ecx, eax
  1519.     mov esi, [line_buffer]
  1520.     mov edi, [pixels_ptr]
  1521.     shr ecx, 2
  1522.     rep movsd
  1523.     mov ecx, eax
  1524.     and ecx, 3
  1525.     rep movsb
  1526.  
  1527.     pop ecx
  1528.     jmp .next_column_cw_low8
  1529.  
  1530. .rotate_cw24:
  1531.   .next_column_cw_low24:
  1532.     dec ecx
  1533.     js  .exchange_dims
  1534.     push    ecx
  1535.  
  1536.     mov edx, [scanline_len_old]
  1537.     add [scanline_len_old], -3
  1538.  
  1539.     mov ecx, [scanline_pixels_new]
  1540.     mov esi, [pixels_ptr]
  1541.     add esi, -3
  1542.     mov edi, [line_buffer]
  1543.     @@: mov al, [esi]
  1544.     mov [edi], al
  1545.     mov al, [esi+1]
  1546.     mov [edi+1], al
  1547.     mov al, [esi+2]
  1548.     mov [edi+2], al
  1549.     sub esi, edx
  1550.     add edi, 3
  1551.     sub ecx, 1
  1552.     jnz @b
  1553.  
  1554.     mov eax, [scanline_pixels_new]
  1555.     dec eax
  1556.     mov edi, [ebx + Image.Data]
  1557.     add edi, [scanline_len_old]
  1558.     lea esi, [edi + 3]
  1559.     mov edx, [scanline_len_old]
  1560.     @@: mov ecx, edx
  1561.     shr ecx, 2
  1562.     rep movsd
  1563.     mov ecx, edx
  1564.     and ecx, 3
  1565.     rep movsb
  1566.     add esi, 3
  1567.     sub eax, 1
  1568.     jnz @b
  1569.  
  1570.     mov eax, [scanline_len_new]
  1571.     sub [pixels_ptr], eax
  1572.     mov ecx, eax
  1573.     mov esi, [line_buffer]
  1574.     mov edi, [pixels_ptr]
  1575.     shr ecx, 2
  1576.     rep movsd
  1577.     mov ecx, eax
  1578.     and ecx, 3
  1579.     rep movsb
  1580.  
  1581.     pop ecx
  1582.     jmp .next_column_cw_low24
  1583.  
  1584. .rotate_cw1:
  1585.     push ecx edx
  1586.  
  1587.     mov eax, [ebx+Image.Height]
  1588.     add eax, 7
  1589.     shr eax, 3
  1590.     mul word[ebx+Image.Width]
  1591.     shl eax, 16
  1592.     shrd eax, edx, 16
  1593.  
  1594.     push eax                                            ; save new data size
  1595.  
  1596.     invoke  mem.alloc, eax
  1597.     or  eax, eax
  1598.     jz  .error
  1599.     push eax                                            ; save pointer to new data
  1600.  
  1601.     mov ecx, 7
  1602.  
  1603.     mov edx, [ebx+Image.Width]
  1604.     mov [pixels_ptr],   edx                             ; we don't use pixels_ptr as it do other procedures, we save there [ebx+Image.Width]
  1605.     mov esi, eax
  1606.     mov edi, [ebx+Image.Data]
  1607.     mov eax, [ebx+Image.Height]
  1608.     dec eax
  1609.     mul [scanline_len_old]
  1610.     add edi, eax
  1611.     mov eax, 7
  1612.     mov edx, 0
  1613.  
  1614.   .rotate_cw1.begin:
  1615.     bt  [edi], ecx
  1616.      jc .rotate_cw1.one
  1617.   .rotate_cw1.zero:
  1618.     btr [esi], eax
  1619.      jmp @f
  1620.   .rotate_cw1.one:
  1621.     bts [esi], eax
  1622.   @@:
  1623.     sub edi, [scanline_len_old]
  1624.     dec [scanline_pixels_new]
  1625.      jz .rotate_cw1.end_of_line
  1626.     dec eax
  1627.      jns .rotate_cw1.begin
  1628.     mov eax, 7
  1629.     inc esi
  1630.      jmp .rotate_cw1.begin
  1631.  
  1632.   .rotate_cw1.end_of_line:
  1633.     dec [pixels_ptr]
  1634.      jz .rotate_cw1.quit
  1635.     inc esi
  1636.     mov eax, [ebx+Image.Height]
  1637.     mov [scanline_pixels_new],   eax
  1638.     mov eax, 7
  1639.     dec ecx
  1640.      js @f
  1641.     mov edi, [ebx+Image.Height]
  1642.     dec edi
  1643.     imul edi, [scanline_len_old]
  1644.     add edi, [ebx+Image.Data]
  1645.     add edi, edx
  1646.      jmp .rotate_cw1.begin
  1647.   @@:
  1648.     mov ecx, 7
  1649.     inc edx
  1650.     cmp edx, [scanline_len_old]
  1651.      je .rotate_cw1.quit
  1652.     mov edi, [ebx+Image.Height]
  1653.     dec edi
  1654.     imul edi, [scanline_len_old]
  1655.     add edi, [ebx+Image.Data]
  1656.     add edi, edx
  1657.      jmp .rotate_cw1.begin
  1658.  
  1659.   .rotate_cw1.quit:
  1660.     pop eax                                             ; get pointer to new data
  1661.     mov esi, eax
  1662.     mov edi, [ebx + Image.Data]
  1663.     pop ecx                                             ; get new data size
  1664.     rep movsb
  1665.  
  1666.     invoke  mem.free, eax
  1667.  
  1668.     pop edx ecx
  1669.      jmp .exchange_dims
  1670.  
  1671.   .flip:
  1672.     jmp .exit
  1673.  
  1674.   .exchange_dims:
  1675.     push    [ebx + Image.Width] [ebx + Image.Height]
  1676.     pop [ebx + Image.Width] [ebx + Image.Height]
  1677.  
  1678.   .exit:
  1679.     invoke  mem.free, [line_buffer]
  1680.     xor eax, eax
  1681.     inc eax
  1682.     pop edi esi ebx
  1683.     ret
  1684.  
  1685.   .error:
  1686.     invoke  mem.free, [line_buffer]
  1687.     xor eax, eax
  1688.     pop edi esi ebx
  1689.     ret
  1690. endp
  1691.  
  1692. ;;================================================================================================;;
  1693. proc img.rotate _img, _rotate_kind ;//////////////////////////////////////////////////////////////;;
  1694. ;;------------------------------------------------------------------------------------------------;;
  1695. ;? Rotate all layers of image                                                                     ;;
  1696. ;;------------------------------------------------------------------------------------------------;;
  1697. ;> _img = pointer to image                                                                        ;;
  1698. ;> _rotate_kind = one of ROTATE_* constants                                                       ;;
  1699. ;;------------------------------------------------------------------------------------------------;;
  1700. ;< eax = false / true                                                                             ;;
  1701. ;;================================================================================================;;
  1702.     push    1
  1703.     mov ebx, [_img]
  1704. @@:
  1705.     mov eax, [ebx + Image.Previous]
  1706.     test    eax, eax
  1707.     jz  .loop
  1708.     mov ebx, eax
  1709.     jmp @b
  1710. .loop:
  1711.     stdcall img.rotate.layer, ebx, [_rotate_kind]
  1712.     test    eax, eax
  1713.     jnz @f
  1714.     mov byte [esp], 0
  1715. @@:
  1716.     mov ebx, [ebx + Image.Next]
  1717.     test    ebx, ebx
  1718.     jnz .loop
  1719.     pop eax
  1720.     ret
  1721. endp
  1722.  
  1723. ;;================================================================================================;;
  1724. proc img.draw _img, _x, _y, _width, _height, _xpos, _ypos ;///////////////////////////////////////;;
  1725. ;;------------------------------------------------------------------------------------------------;;
  1726. ;? Draw image in the window                                                                       ;;
  1727. ;;------------------------------------------------------------------------------------------------;;
  1728. ;> _img = pointer to image                                                                        ;;
  1729. ;>_x = x-coordinate in the window                                                                 ;;
  1730. ;>_y = y-coordinate in the window                                                                 ;;
  1731. ;>_width = maximum width to draw                                                                  ;;
  1732. ;>_height = maximum height to draw                                                                ;;
  1733. ;>_xpos = offset in image by x-axis                                                               ;;
  1734. ;>_ypos = offset in image by y-axis                                                               ;;
  1735. ;;------------------------------------------------------------------------------------------------;;
  1736. ;< no return value                                                                                ;;
  1737. ;;================================================================================================;;
  1738.     push    ebx esi edi
  1739.     mov ebx, [_img]
  1740.     stdcall img._.validate, ebx
  1741.     test    eax, eax
  1742.     jnz .done
  1743.     mov ecx, [ebx + Image.Width]
  1744.     sub ecx, [_xpos]
  1745.     jbe .done
  1746.     cmp ecx, [_width]
  1747.     jb  @f
  1748.     mov ecx, [_width]
  1749. @@:
  1750.     mov edx, [ebx + Image.Height]
  1751.     sub edx, [_ypos]
  1752.     jbe .done
  1753.     cmp edx, [_height]
  1754.     jb  @f
  1755.     mov edx, [_height]
  1756. @@:
  1757.     mov eax, [ebx + Image.Width]
  1758.     sub eax, ecx
  1759.     call    img._.get_scanline_len
  1760.     shl ecx, 16
  1761.     add ecx, edx
  1762.     push    eax
  1763.     mov eax, [ebx + Image.Width]
  1764.     imul    eax, [_ypos]
  1765.     add eax, [_xpos]
  1766.     call    img._.get_scanline_len
  1767.     add eax, [ebx + Image.Data]
  1768.     mov edx, [_x - 2]
  1769.     mov dx, word [_y]
  1770.     mov esi, [ebx + Image.Type]
  1771.     mov esi, [type2bpp + (esi-1)*4]
  1772.     mov edi, [ebx + Image.Palette]
  1773.     xchg    eax, ebx
  1774.     pop eax
  1775.     push    ebp
  1776.     push    65
  1777.     pop ebp
  1778.     xchg    eax, ebp
  1779.     int 40h
  1780.     pop ebp
  1781. .done:
  1782.     pop edi esi ebx
  1783.     ret
  1784. endp
  1785.  
  1786. ;;================================================================================================;;
  1787. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1788. ;;================================================================================================;;
  1789. ;! Below are private procs you should never call directly from your code                          ;;
  1790. ;;================================================================================================;;
  1791. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1792. ;;================================================================================================;;
  1793.  
  1794.  
  1795. ;;================================================================================================;;
  1796. proc img._.validate, _img ;///////////////////////////////////////////////////////////////////////;;
  1797. ;;------------------------------------------------------------------------------------------------;;
  1798. ;? --- TBD ---                                                                                    ;;
  1799. ;;------------------------------------------------------------------------------------------------;;
  1800. ;> --- TBD ---                                                                                    ;;
  1801. ;;------------------------------------------------------------------------------------------------;;
  1802. ;< --- TBD ---                                                                                    ;;
  1803. ;;================================================================================================;;
  1804.     xor eax, eax
  1805.     ret
  1806. endp
  1807.  
  1808. ;;================================================================================================;;
  1809. proc img._.new ;//////////////////////////////////////////////////////////////////////////////////;;
  1810. ;;------------------------------------------------------------------------------------------------;;
  1811. ;? --- TBD ---                                                                                    ;;
  1812. ;;------------------------------------------------------------------------------------------------;;
  1813. ;> --- TBD ---                                                                                    ;;
  1814. ;;------------------------------------------------------------------------------------------------;;
  1815. ;< eax = 0 / pointer to image                                                                     ;;
  1816. ;;================================================================================================;;
  1817.     invoke  mem.alloc, sizeof.Image
  1818.     test    eax, eax
  1819.     jz  @f
  1820.     push    ecx
  1821.     xor ecx, ecx
  1822.     mov [eax + Image.Data], ecx
  1823.     mov [eax + Image.Type], ecx
  1824.     mov [eax + Image.Flags], ecx
  1825.     mov [eax + Image.Extended], ecx
  1826.     mov [eax + Image.Previous], ecx
  1827.     mov [eax + Image.Next], ecx
  1828.     pop ecx
  1829. @@:
  1830.     ret
  1831. endp
  1832.  
  1833. ;;================================================================================================;;
  1834. proc img._.delete _img ;//////////////////////////////////////////////////////////////////////////;;
  1835. ;;------------------------------------------------------------------------------------------------;;
  1836. ;? --- TBD ---                                                                                    ;;
  1837. ;;------------------------------------------------------------------------------------------------;;
  1838. ;> --- TBD ---                                                                                    ;;
  1839. ;;------------------------------------------------------------------------------------------------;;
  1840. ;< eax = false / true                                                                             ;;
  1841. ;;================================================================================================;;
  1842.     push    edx
  1843.     mov edx, [_img]
  1844.     cmp [edx + Image.Data], 0
  1845.     je  @f
  1846.     invoke  mem.free, [edx + Image.Data]
  1847.     @@: cmp [edx + Image.Extended], 0
  1848.     je  @f
  1849.     invoke  mem.free, [edx + Image.Extended]
  1850.     @@: invoke  mem.free, edx
  1851.     pop edx
  1852.     ret
  1853. endp
  1854.  
  1855. ;;================================================================================================;;
  1856. proc img._.resize_data _img, _width, _height ;////////////////////////////////////////////////////;;
  1857. ;;------------------------------------------------------------------------------------------------;;
  1858. ;? --- TBD ---                                                                                    ;;
  1859. ;;------------------------------------------------------------------------------------------------;;
  1860. ;> --- TBD ---                                                                                    ;;
  1861. ;;------------------------------------------------------------------------------------------------;;
  1862. ;< --- TBD ---                                                                                    ;;
  1863. ;;================================================================================================;;
  1864.     push    ebx esi
  1865.     mov ebx, [_img]
  1866.     mov eax, [_height]
  1867. ; our memory is limited, [_width]*[_height] must not overflow
  1868. ; image with width or height greater than 65535 is most likely bogus
  1869.     cmp word [_width+2], 0
  1870.     jnz .error
  1871.     cmp word [_height+2], 0
  1872.     jnz .error
  1873.     imul    eax, [_width]
  1874.     test    eax, eax
  1875.     jz  .error
  1876. ; do not allow images which require too many memory
  1877.     cmp eax, 4000000h
  1878.     jae .error
  1879.     cmp [ebx + Image.Type], Image.bpp1
  1880.     jz  .bpp1
  1881.     cmp [ebx + Image.Type], Image.bpp8
  1882.     jz  .bpp8
  1883.     cmp [ebx + Image.Type], Image.bpp24
  1884.     jz  .bpp24
  1885. .bpp32:
  1886.     shl eax, 2
  1887.     jmp @f
  1888. .bpp24:
  1889.     lea eax, [eax*3]
  1890.     jmp @f
  1891. .bpp8:
  1892.     add eax, 256*4  ; for palette
  1893.     jmp @f
  1894. .bpp1:
  1895.     mov eax, [_width]
  1896.     add eax, 7
  1897.     shr eax, 3
  1898.     mul word[_height]
  1899.     shl eax, 16
  1900.     mov ax,  dx
  1901.     ror eax, 16
  1902.  
  1903.     push ebx
  1904.     mov ebx, eax
  1905.  
  1906.     mov eax, [_height]
  1907.     add eax, 7
  1908.     shr eax, 3
  1909.     mul word[_width]
  1910.     shl eax, 16
  1911.     mov ax,  dx
  1912.     ror eax, 16
  1913.  
  1914.     cmp eax, ebx
  1915.      jge .bpp1.skip
  1916.     mov eax, ebx
  1917.   .bpp1.skip:
  1918.     pop ebx
  1919.  
  1920.     add eax, 2*4    ; for palette
  1921. @@:
  1922.     mov esi, eax
  1923.     invoke  mem.realloc, [ebx + Image.Data], eax
  1924.     or  eax, eax
  1925.     jz  .error
  1926.  
  1927.     mov [ebx + Image.Data], eax
  1928.     push    [_width]
  1929.     pop [ebx + Image.Width]
  1930.     push    [_height]
  1931.     pop [ebx + Image.Height]
  1932.     cmp [ebx + Image.Type], Image.bpp8
  1933.     jnz @f
  1934.     lea esi, [eax + esi - 256*4]
  1935.     mov [ebx + Image.Palette], esi
  1936.     jmp .ret
  1937. @@:
  1938.     cmp [ebx + Image.Type], Image.bpp1
  1939.     jnz .ret
  1940.     lea esi, [eax + esi - 2*4]
  1941.     mov [ebx + Image.Palette], esi
  1942.     jmp .ret
  1943.  
  1944.   .error:
  1945.     xor eax, eax
  1946.   .ret:
  1947.     pop esi ebx
  1948.     ret
  1949. endp
  1950.  
  1951. ;;================================================================================================;;
  1952. img._.get_scanline_len: ;/////////////////////////////////////////////////////////////////////////;;
  1953. ;;------------------------------------------------------------------------------------------------;;
  1954. ;? --- TBD ---                                                                                    ;;
  1955. ;;------------------------------------------------------------------------------------------------;;
  1956. ;> --- TBD ---                                                                                    ;;
  1957. ;;------------------------------------------------------------------------------------------------;;
  1958. ;< --- TBD ---                                                                                    ;;
  1959. ;;================================================================================================;;
  1960.     cmp [ebx + Image.Type], Image.bpp1
  1961.     jz  .bpp1.1
  1962.     cmp [ebx + Image.Type], Image.bpp8
  1963.     jz  .bpp8.1
  1964.     cmp [ebx + Image.Type], Image.bpp24
  1965.     jz  .bpp24.1
  1966.     add eax, eax
  1967.     cmp [ebx + Image.Type], Image.bpp32
  1968.     jnz .quit
  1969.     add eax, eax
  1970.     jmp .quit
  1971. .bpp24.1:
  1972.     lea eax, [eax*3]
  1973.     jmp .quit
  1974. .bpp1.1:
  1975.     add eax, 7
  1976.     shr eax, 3
  1977. .bpp8.1:
  1978. .quit:
  1979.     ret
  1980.  
  1981.  
  1982. ;;================================================================================================;;
  1983. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1984. ;;================================================================================================;;
  1985. ;! Below is private data you should never use directly from your code                             ;;
  1986. ;;================================================================================================;;
  1987. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1988. ;;================================================================================================;;
  1989.  
  1990. align 4
  1991. img._.formats_table:
  1992.   .bmp dd img.is.bmp, img.decode.bmp, img.encode.bmp
  1993.   .ico dd img.is.ico, img.decode.ico_cur, img.encode.ico
  1994.   .cur dd img.is.cur, img.decode.ico_cur, img.encode.cur
  1995.   .gif dd img.is.gif, img.decode.gif, img.encode.gif
  1996.   .png dd img.is.png, img.decode.png, img.encode.png
  1997.   .jpg dd img.is.jpg, img.decode.jpg, img.encode.jpg
  1998.   .tga dd img.is.tga, img.decode.tga, img.encode.tga
  1999.   .pcx dd img.is.pcx, img.decode.pcx, img.encode.pcx
  2000.   .z80 dd img.is.z80, img.decode.z80, img.encode.z80 ;this must be the last entry as there are no
  2001.   ;signatures in z80 screens at all
  2002.        dd 0
  2003.  
  2004. align 4
  2005. type2bpp    dd  8, 24, 32, 15, 16, 1
  2006. img._.do_rgb.handlers:
  2007.     dd  img._.do_rgb.bpp8
  2008.     dd  img._.do_rgb.bpp24
  2009.     dd  img._.do_rgb.bpp32
  2010.     dd  img._.do_rgb.bpp15.amd  ; can be overwritten in lib_init
  2011.     dd  img._.do_rgb.bpp16.amd  ; can be overwritten in lib_init
  2012.     dd  img._.do_rgb.bpp1
  2013.  
  2014. img.flip.layer.handlers_horz:
  2015.     dd  img.flip.layer.bpp8_horz
  2016.     dd  img.flip.layer.bpp24_horz
  2017.     dd  img.flip.layer.bpp32_horz
  2018.     dd  img.flip.layer.bpp1x_horz
  2019.     dd  img.flip.layer.bpp1x_horz
  2020.     dd  img.flip.layer.bpp1_horz
  2021.  
  2022. ;;================================================================================================;;
  2023. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  2024. ;;================================================================================================;;
  2025. ;! Exported functions section                                                                     ;;
  2026. ;;================================================================================================;;
  2027. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  2028. ;;================================================================================================;;
  2029.  
  2030.  
  2031. align 4
  2032. @EXPORT:
  2033.  
  2034. export                        \
  2035.     lib_init    , 'lib_init'        , \
  2036.     0x00050007  , 'version'     , \
  2037.     img.is_img  , 'img_is_img'      , \
  2038.     img.info    , 'img_info'        , \
  2039.     img.from_file   , 'img_from_file'   , \
  2040.     img.to_file , 'img_to_file'     , \
  2041.     img.from_rgb    , 'img_from_rgb'    , \
  2042.     img.to_rgb  , 'img_to_rgb'      , \
  2043.     img.to_rgb2 , 'img_to_rgb2'     , \
  2044.     img.decode  , 'img_decode'      , \
  2045.     img.encode  , 'img_encode'      , \
  2046.     img.create  , 'img_create'      , \
  2047.     img.destroy , 'img_destroy'     , \
  2048.     img.destroy.layer, 'img_destroy_layer', \
  2049.     img.count   , 'img_count'       , \
  2050.     img.lock_bits   , 'img_lock_bits'   , \
  2051.     img.unlock_bits , 'img_unlock_bits' , \
  2052.     img.flip    , 'img_flip'        , \
  2053.     img.flip.layer  , 'img_flip_layer'  , \
  2054.     img.rotate  , 'img_rotate'      , \
  2055.     img.rotate.layer, 'img_rotate_layer', \
  2056.     img.draw        , 'img_draw'
  2057.  
  2058. ; import from deflate unpacker
  2059. ; is initialized only when PNG loading is requested
  2060. align 4
  2061. @IMPORT:
  2062.  
  2063. library archiver, 'archiver.obj'
  2064. import  archiver, \
  2065.     deflate_unpack2, 'deflate_unpack2'
  2066.  
  2067. align 4
  2068. ; mutex for unpacker loading
  2069. deflate_loader_mutex    dd  0
  2070.  
  2071. ; default palette for GIF - b&w
  2072. gif_default_palette:
  2073.     db  0, 0, 0
  2074.     db  0xFF, 0xFF, 0xFF
  2075.  
  2076. section '.data' data readable writable align 16
  2077. ; uninitialized data - global constant tables
  2078. mem.alloc   dd ?
  2079. mem.free    dd ?
  2080. mem.realloc dd ?
  2081. dll.load    dd ?
  2082.  
  2083. ; data for YCbCr -> RGB translation
  2084. color_table_1       rd  256
  2085. color_table_2       rd  256
  2086. color_table_3       rd  256
  2087. color_table_4       rd  256
  2088.