Subversion Repositories Kolibri OS

Rev

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