Subversion Repositories Kolibri OS

Rev

Rev 722 | Rev 999 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;================================================================================================;;
  2. ;;//// gif.asm //// (c) mike.dld, 2007-2008 //////////////////////////////////////////////////////;;
  3. ;;================================================================================================;;
  4. ;;//// Partial (c) by Willow, Diamond and HidnPlayr //////////////////////////////////////////////;;
  5. ;;================================================================================================;;
  6. ;;                                                                                                ;;
  7. ;; This file is part of Common development libraries (Libs-Dev).                                  ;;
  8. ;;                                                                                                ;;
  9. ;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
  10. ;; General Public License as published by the Free Software Foundation, either version 3 of the   ;;
  11. ;; License, or (at your option) any later version.                                                ;;
  12. ;;                                                                                                ;;
  13. ;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
  14. ;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
  15. ;; General Public License for more details.                                                       ;;
  16. ;;                                                                                                ;;
  17. ;; You should have received a copy of the GNU General Public License along with Libs-Dev. If not, ;;
  18. ;; see <http://www.gnu.org/licenses/>.                                                            ;;
  19. ;;                                                                                                ;;
  20. ;;================================================================================================;;
  21. ;;                                                                                                ;;
  22. ;; References:                                                                                    ;;
  23. ;;   1. GIF LITE v3.0 (2004-2007)                                                                 ;;
  24. ;;      by Willow and Diamond                                                                     ;;
  25. ;;      svn://kolibrios.org/programs/media/gifview/trunk/gif_lite.inc                             ;;
  26. ;;   2. "GIF File Format Summary"                                                                 ;;
  27. ;;      from "Encyclopedia of Graphics File Formats" by O'Reilly                                  ;;
  28. ;;      http://www.fileformat.info/format/gif/                                                    ;;
  29. ;;   3. "LZW and GIF explained" (1987)                                                            ;;
  30. ;;      by Steve Blackstock, IEEE                                                                 ;;
  31. ;;      http://www.cis.udel.edu/~amer/CISC651/lzw.and.gif.explained.html                          ;;
  32. ;;   4. "Graphics Interchange Format (tm)" (June 15, 1987)                                        ;;
  33. ;;      by CompuServe Incorporated                                                                ;;
  34. ;;      http://examples.oreilly.de/english_examples/gff/CDROM/GFF/VENDSPEC/GIF/GIF87A.TXT         ;;
  35. ;;   5. "Graphics Interchange Format (sm)" (July 31, 1990)                                        ;;
  36. ;;      by CompuServe Incorporated                                                                ;;
  37. ;;      http://examples.oreilly.de/english_examples/gff/CDROM/GFF/VENDSPEC/GIF/GIF89A.TXT         ;;
  38. ;;                                                                                                ;;
  39. ;;================================================================================================;;
  40.  
  41.  
  42. include 'gif.inc'
  43.  
  44. ;;================================================================================================;;
  45. proc img.is.gif _data, _length ;//////////////////////////////////////////////////////////////////;;
  46. ;;------------------------------------------------------------------------------------------------;;
  47. ;? Determine if raw data could be decoded (is in GIF format)                                      ;;
  48. ;;------------------------------------------------------------------------------------------------;;
  49. ;> _data = raw data as read from file/stream                                                      ;;
  50. ;> _length = data length                                                                          ;;
  51. ;;------------------------------------------------------------------------------------------------;;
  52. ;< eax = false / true                                                                             ;;
  53. ;;================================================================================================;;
  54.         cmp     [_length], 6
  55.         jb      .nope
  56.         mov     eax, [_data]
  57.         cmp     dword[eax], 'GIF8'
  58.         jne     .nope
  59.         cmp     word[eax + 4], '7a'
  60.         je      .yep
  61.         cmp     word[eax + 4], '9a'
  62.         je      .yep
  63.  
  64.   .nope:
  65.         xor     eax, eax
  66.         ret
  67.  
  68.   .yep:
  69.         xor     eax, eax
  70.         inc     eax
  71.         ret
  72. endp
  73.  
  74. ;;================================================================================================;;
  75. proc img.decode.gif _data, _length ;//////////////////////////////////////////////////////////////;;
  76. ;;------------------------------------------------------------------------------------------------;;
  77. ;? Decode data into image if it contains correctly formed raw data in GIF format                  ;;
  78. ;;------------------------------------------------------------------------------------------------;;
  79. ;> _data = raw data as read from file/stream                                                      ;;
  80. ;> _length = data length                                                                          ;;
  81. ;;------------------------------------------------------------------------------------------------;;
  82. ;< eax = 0 (error) or pointer to image                                                            ;;
  83. ;;================================================================================================;;
  84. locals
  85.   img                dd ?
  86.   global_color_table dd ?
  87. endl
  88.  
  89.         push    ebx
  90.  
  91.         stdcall img.is.gif, [_data], [_length]
  92.         or      eax, eax
  93.         jz      .error
  94.  
  95.         mov     ebx, [_data]
  96. ;       cmp     [ebx + bmp.Header.info.Compression], bmp.BI_RGB
  97. ;       je      @f
  98. ;       mov     eax, [ebx + bmp.Header.file.Size]
  99. ;       cmp     eax, [_length]
  100. ;       jne     .error
  101.  
  102.         test    [ebx + gif.Header.lsd.Packed], gif.LSD.Packed.GlobalColorTableFlag
  103.         jz      @f
  104.         lea     eax, [ebx + sizeof.gif.Header]
  105.         mov     [global_color_table], eax
  106.         mov     cl, [ebx + gif.Header.lsd.Packed]
  107.         and     cl, gif.LSD.Packed.SizeOfGlobalColorTableMask
  108.         shr     cl, gif.LSD.Packed.SizeOfGlobalColorTableShift
  109.         inc     cl
  110.         mov     eax, 1
  111.         shl     eax, cl
  112.         lea     eax, [eax * 3]
  113.         add     ebx, eax
  114.     @@: add     ebx, sizeof.gif.Header
  115.  
  116.         mov     [img], 0
  117.  
  118. ;   @@: cmp     byte[ebx + gif.Block.Introducer], gif.Block.Introducer.Extension
  119. ;       jne     .next_image
  120. ;       cmp     byte[ebx + gif.Extension.Label], gif.Extension.Label.Comment
  121. ;       jne     .error
  122. ;       add     ebx, sizeof.gif.Extension
  123. ;       stdcall ._.skip_data
  124. ;       mov     ebx, eax
  125. ;       jmp     @b
  126.  
  127.   .next_image:
  128.         stdcall img._.new
  129.         or      eax, eax
  130.         jz      .error
  131.         mov     edx, [img]
  132.         mov     [eax + Image.Previous], edx
  133.         mov     [img], eax
  134.         mov     edx, eax
  135.  
  136.         mov     ecx, sizeof.gif.Image
  137.         invoke  mem.alloc, ecx
  138.         or      eax, eax
  139.         jz      .error
  140.         mov     [edx + Image.Extended], eax
  141.  
  142.         stdcall ._.process_extensions
  143.  
  144.         cmp     byte[ebx + gif.Block.Introducer], gif.Block.Introducer.ImageDescriptor
  145.         jne     .error
  146.         movzx   eax, [ebx + gif.ImageDescriptor.Width]
  147.         movzx   ecx, [ebx + gif.ImageDescriptor.Height]
  148.         stdcall img._.resize_data, [img], eax, ecx
  149.         or      eax, eax
  150.         jz      .error
  151.  
  152.         xor     ecx, ecx
  153.         mov     eax, [edx + Image.Extended]
  154.         test    [ebx + gif.ImageDescriptor.Packed], gif.ID.Packed.LocalColorTableFlag
  155.         jz      @f
  156.         mov     cl, [ebx + gif.ImageDescriptor.Packed]
  157.         and     cl, gif.ID.Packed.SizeOfLocalColorTableMask
  158.         shr     cl, gif.ID.Packed.SizeOfLocalColorTableShift
  159.         inc     cl
  160.         mov     eax, 1
  161.         shl     eax, cl
  162.         lea     ecx, [eax * sizeof.gif.RgbTriplet]
  163.         lea     eax, [ecx + sizeof.gif.Image]
  164.         invoke  mem.realloc, [edx + Image.Extended], eax
  165.         or      eax, eax
  166.         jz      .error
  167.         mov     [edx + Image.Extended], eax
  168.     @@: mov     esi, ebx
  169.         lea     edi, [eax + sizeof.gif.GraphicsControlExtension]
  170.         add     ecx, sizeof.gif.ImageDescriptor
  171.         rep     movsb
  172.  
  173.         mov     eax, [global_color_table]
  174.         test    [ebx + gif.ImageDescriptor.Packed], gif.ID.Packed.LocalColorTableFlag
  175.         jz      @f
  176.         lea     eax, [ebx + sizeof.gif.ImageDescriptor]
  177.     @@: mov     ebx, esi
  178.         stdcall ._.process_image, eax
  179.  
  180.   .decoded:
  181.         or      eax, eax
  182.         jz      @f
  183.         stdcall img.destroy, [img]
  184.         jmp     .error
  185.        
  186.     @@: mov     eax, [img]
  187.         ret
  188.  
  189.   .error:
  190.         xor     eax, eax
  191.         pop     ebx
  192.         ret
  193. endp
  194.  
  195. ;;================================================================================================;;
  196. proc img.encode.gif _img, _p_length ;/////////////////////////////////////////////////////////////;;
  197. ;;------------------------------------------------------------------------------------------------;;
  198. ;? Encode image into raw data in GIF format                                                       ;;
  199. ;;------------------------------------------------------------------------------------------------;;
  200. ;> _img = pointer to image                                                                        ;;
  201. ;;------------------------------------------------------------------------------------------------;;
  202. ;< eax = 0 (error) or pointer to encoded data                                                     ;;
  203. ;< _p_length = encoded data length                                                                ;;
  204. ;;================================================================================================;;
  205.         xor     eax, eax
  206.         ret
  207. endp
  208.  
  209.  
  210. ;;================================================================================================;;
  211. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  212. ;;================================================================================================;;
  213. ;! Below are private procs you should never call directly from your code                          ;;
  214. ;;================================================================================================;;
  215. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  216. ;;================================================================================================;;
  217.  
  218.  
  219. ;;================================================================================================;;
  220. proc img.decode.gif._.skip_data ;/////////////////////////////////////////////////////////////////;;
  221. ;;------------------------------------------------------------------------------------------------;;
  222. ;? --- TBD ---                                                                                    ;;
  223. ;;------------------------------------------------------------------------------------------------;;
  224. ;> ebx = pointer to data blocks array                                                             ;;
  225. ;;------------------------------------------------------------------------------------------------;;
  226. ;< eax = pointer to data right after data blocks array                                            ;;
  227. ;;================================================================================================;;
  228.         push    ecx
  229.         xor     ecx, ecx
  230.     @@: mov     cl, [esi]
  231.         or      cl, cl
  232.         jz      @f
  233.         lea     esi, [esi + ecx + 1]
  234.         jmp     @b
  235.     @@: pop     ecx
  236.         ret
  237. endp
  238.  
  239. ;;================================================================================================;;
  240. proc img.decode.gif._.process_extensions ;////////////////////////////////////////////////////////;;
  241. ;;------------------------------------------------------------------------------------------------;;
  242. ;? --- TBD ---                                                                                    ;;
  243. ;;------------------------------------------------------------------------------------------------;;
  244. ;> ebx = raw image data                                                                           ;;
  245. ;> edx = image data                                                                               ;;
  246. ;;------------------------------------------------------------------------------------------------;;
  247. ;< --- TBD ---                                                                                    ;;
  248. ;;================================================================================================;;
  249.         push    edx
  250.         mov     esi, ebx
  251.  
  252.   .next_block:
  253.         mov     al, [esi + gif.Block.Introducer]
  254.         cmp     al, gif.Block.Introducer.Extension
  255.         je      .ext_block
  256. ;       cmp     al, gif.Block.Introducer.ImageDescriptor
  257. ;       je      .exit
  258. ;       cmp     al, gif.Block.Introducer.EndOfFile
  259. ;       je      .exit
  260.         jmp     .exit
  261.  
  262.   .ext_block:
  263.         mov     al, [esi + gif.Extension.Label]
  264.         cmp     al, gif.Extension.Label.PlainText
  265.         je      .plain_text_ext
  266.         cmp     al, gif.Extension.Label.GraphicsControl
  267.         je      .graphics_control_ext
  268.         cmp     al, gif.Extension.Label.Comment
  269.         je      .comment_ext
  270.         cmp     al, gif.Extension.Label.Application
  271.         je      .application_ext
  272.         jmp     .exit
  273.  
  274.   .plain_text_ext:
  275.         add     esi, gif.PlainTextExtension.PlainTextData
  276.         stdcall img.decode.gif._.skip_data
  277.         jmp     .next_ext_block
  278.  
  279.   .graphics_control_ext:
  280.         push    edi
  281.         mov     edi, [edx + Image.Extended]
  282.         add     edi, gif.Image.gce
  283.         mov     ecx, sizeof.gif.GraphicsControlExtension
  284.         rep     movsb
  285.         pop     edi
  286.         jmp     .next_ext_block
  287.  
  288.   .comment_ext:
  289.         add     esi, gif.CommentExtension.CommentData
  290.         stdcall img.decode.gif._.skip_data
  291.         jmp     .next_ext_block
  292.  
  293.   .application_ext:
  294.         add     esi, gif.ApplicationExtension.ApplicationData
  295.         stdcall img.decode.gif._.skip_data
  296.         jmp     .next_ext_block
  297.  
  298.   .next_ext_block:
  299.         mov     al, [esi + gif.Block.Introducer]
  300.         cmp     al, gif.Block.Introducer.EndOfData
  301.         jne     .exit
  302.         inc     esi
  303.         jmp     .next_block
  304.  
  305.   .exit:
  306.         mov     ebx, esi
  307.         pop     edx
  308.         ret
  309. endp
  310.  
  311. ;;================================================================================================;;
  312. proc img.decode.gif._.process_image _color_table ;////////////////////////////////////////////////;;
  313. ;;------------------------------------------------------------------------------------------------;;
  314. ;? --- TBD ---                                                                                    ;;
  315. ;;------------------------------------------------------------------------------------------------;;
  316. ;> ebx = raw image data                                                                           ;;
  317. ;> edx = image data                                                                               ;;
  318. ;;------------------------------------------------------------------------------------------------;;
  319. ;< --- TBD ---                                                                                    ;;
  320. ;;================================================================================================;;
  321. locals
  322.   width      dd ?
  323.   img_start  dd ?
  324.   img_end    dd ?
  325.   row_end    dd ?
  326.   pass       dd ?
  327.   codesize   dd ?
  328.   compsize   dd ?
  329.   workarea   dd ?
  330.   block_ofs  dd ?
  331.   bit_count  dd ?
  332.   CC         dd ?
  333.   EOI        dd ?
  334. endl
  335.  
  336.         invoke  mem.alloc, 16 * 1024
  337.         mov     [workarea], eax
  338.         or      eax, eax
  339.         jz      .error
  340.  
  341.         mov     ecx, [edx + Image.Width]
  342.         mov     [width], ecx
  343.         mov     eax, [edx + Image.Height]
  344.         imul    eax, ecx
  345. ;       lea     eax, [eax * 3]
  346.         shl     eax, 2
  347.         mov     [img_end], eax
  348.         inc     eax
  349.         mov     [row_end], eax
  350.         and     [pass], 0
  351.         mov     eax, [edx + Image.Extended]
  352.         test    [eax + gif.Image.info.Packed], gif.ID.Packed.InterleaceFlag
  353.         jz      @f
  354. ;       lea     ecx, [ecx * 3]
  355.         shl     ecx, 2
  356.         mov     [row_end], ecx
  357.  
  358.     @@: mov     esi, ebx
  359.         mov     edi, [edx + Image.Data]
  360.  
  361.         push    edi
  362.         movzx   ecx, byte[esi]
  363.         inc     esi
  364.         mov     [codesize], ecx
  365.         inc     [codesize]
  366.         mov     edi, [workarea]
  367.         xor     eax, eax
  368.         lodsb                           ; eax - block_count
  369.         add     eax, esi
  370.         mov     [block_ofs], eax
  371.         mov     [bit_count], 8
  372.         mov     eax, 1
  373.         shl     eax, cl
  374.         mov     [CC], eax
  375.         mov     ecx, eax
  376.         inc     eax
  377.         mov     [EOI], eax
  378.         mov     eax, gif.Null shl 16
  379.   .filltable:
  380.         stosd
  381.         inc     eax
  382.         loop    .filltable
  383.         pop     edi
  384.         mov     [img_start], edi
  385.         add     [img_end], edi
  386.         add     [row_end], edi
  387.   .reinit:
  388.         mov     edx, [EOI]
  389.         inc     edx
  390.         push    [codesize]
  391.         pop     [compsize]
  392.         call    .get_symbol
  393.         cmp     eax, [CC]
  394.         je      .reinit
  395.         call    .output
  396.   .cycle:
  397.         movzx   ebx, ax
  398.         call    .get_symbol
  399.         cmp     eax, edx
  400.         jae     .notintable
  401.         cmp     eax, [CC]
  402.         je      .reinit
  403.         cmp     eax, [EOI]
  404.         je      .end
  405.         call    .output
  406.   .add:
  407.         mov     ecx, [workarea]
  408.         mov     [ecx + edx * 4], ebx
  409.         cmp     edx, 0x00000FFF
  410.         jae     .cycle
  411.         inc     edx
  412.         bsr     ebx, edx
  413.         cmp     ebx, [compsize]
  414.         jne     .noinc
  415.         inc     [compsize]
  416.   .noinc:
  417.         jmp     .cycle
  418.   .notintable:
  419.         push    eax
  420.         mov     eax, ebx
  421.         call    .output
  422.         push    ebx
  423.         movzx   eax, bx
  424.         call    .output
  425.         pop     ebx eax
  426.         jmp     .add
  427.   .end:
  428.         mov     edi, [img_end]
  429.         xor     eax, eax
  430.  
  431.   .exit:
  432.         cmp     [workarea], 0
  433.         je      @f
  434.         invoke  mem.free, [workarea]
  435.     @@: xor     eax, eax
  436.         ret
  437.  
  438.   .error:
  439.         cmp     [workarea], 0
  440.         je      @f
  441.         invoke  mem.free, [workarea]
  442.     @@: xor     eax, eax
  443.         inc     eax
  444.         ret
  445.  
  446. ;;------------------------------------------------------------------------------------------------;;
  447.  
  448. img.decode.gif._.process_image.get_symbol:
  449.         mov     ecx, [compsize]
  450.         push    ecx
  451.         xor     eax, eax
  452.  
  453.   .shift:
  454.         ror     byte[esi], 1
  455.         rcr     eax,1
  456.         dec     [bit_count]
  457.         jnz     .loop1
  458.         inc     esi
  459.         cmp     esi, [block_ofs]
  460.         jb      .noblock
  461.         push    eax
  462.         xor     eax, eax
  463.         lodsb
  464.         test    eax, eax
  465.         jnz     .nextbl
  466.         mov     eax, [EOI]
  467.         sub     esi, 2
  468.         add     esp, 8
  469.         jmp     .exit
  470.  
  471.   .nextbl:
  472.         add     eax, esi
  473.         mov     [block_ofs], eax
  474.         pop     eax
  475.  
  476.   .noblock:
  477.         mov     [bit_count], 8
  478.  
  479.   .loop1:
  480.         loop    .shift
  481.         pop     ecx
  482.         rol     eax, cl
  483.  
  484.   .exit:
  485.         xor     ecx, ecx
  486.         retn
  487.  
  488. ;;------------------------------------------------------------------------------------------------;;
  489.  
  490. img.decode.gif._.process_image.output:
  491.         push    esi eax edx
  492.         mov     edx, [workarea]
  493.  
  494.   .next:
  495.         pushw   [edx + eax * 4]
  496.         mov     ax, [edx + eax * 4 + 2]
  497.         inc     ecx
  498.         cmp     ax, gif.Null
  499.         jnz     .next
  500.         shl     ebx, 16
  501.         mov     bx, [esp]
  502.  
  503.   .loop2:
  504.         pop     ax
  505.  
  506.         lea     esi, [eax * 3]
  507.         add     esi, [_color_table]
  508.  
  509.         mov     esi, [esi]
  510.         bswap   esi
  511.         shr     esi, 8
  512.         mov     [edi], esi
  513.         add     edi, 4
  514.  
  515.         cmp     edi, [row_end]
  516.         jb      .norowend
  517.         mov     eax, [width]
  518. ;       lea     eax, [eax * 3]
  519.         shl     eax, 2
  520.         push    eax
  521.         sub     edi, eax
  522.         add     eax, eax
  523.         cmp     [pass], 3
  524.         je      @f
  525.         add     eax, eax
  526.         cmp     [pass], 2
  527.         je      @f
  528.         add     eax, eax
  529.     @@: add     edi, eax
  530.         pop     eax
  531.         cmp     edi, [img_end]
  532.         jb      .nextrow
  533.         mov     edi, [img_start]
  534.         inc     [pass]
  535.         add     edi, eax
  536.         cmp     [pass], 3
  537.         je      @f
  538.         add     edi, eax
  539.         cmp     [pass], 2
  540.         je      @f
  541.         add     edi, eax
  542.         add     edi, eax
  543.     @@:
  544.  
  545.   .nextrow:
  546.         add     eax, edi
  547.         mov     [row_end], eax
  548.         xor     eax, eax
  549.  
  550.   .norowend:
  551.         loop    .loop2
  552.         pop     edx eax esi
  553.         retn
  554.  
  555. endp
  556.  
  557.  
  558. ;;================================================================================================;;
  559. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  560. ;;================================================================================================;;
  561. ;! Below is private data you should never use directly from your code                             ;;
  562. ;;================================================================================================;;
  563. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  564. ;;================================================================================================;;
  565.  
  566.  
  567. ;
  568.