Subversion Repositories Kolibri OS

Rev

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