Subversion Repositories Kolibri OS

Rev

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