Subversion Repositories Kolibri OS

Rev

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