Subversion Repositories Kolibri OS

Rev

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