Subversion Repositories Kolibri OS

Rev

Rev 2733 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;================================================================================================;;
  2. ;;//// pnm.asm //// (c) dunkaist, 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. include 'pnm.inc'
  21.  
  22. ;;================================================================================================;;
  23. proc img.is.pnm _data, _length ;//////////////////////////////////////////////////////////////////;;
  24. ;;------------------------------------------------------------------------------------------------;;
  25. ;? Determine if raw data could be decoded (is in pnm format)                                      ;;
  26. ;;------------------------------------------------------------------------------------------------;;
  27. ;> _data = raw data as read from file/stream                                                      ;;
  28. ;> _length = data length                                                                          ;;
  29. ;;------------------------------------------------------------------------------------------------;;
  30. ;< eax = false / true                                                                             ;;
  31. ;;================================================================================================;;
  32.  
  33.         xor     eax, eax
  34.  
  35.         mov     ecx, [_data]
  36.         mov     cx, word[ecx]
  37.         xchg    cl, ch
  38.         cmp     cx, '1P'
  39.         jb      .is_not_pnm
  40.         cmp     cx, '6P'
  41.         ja      .is_not_pnm
  42.  
  43.   .is_pnm:
  44.         inc     eax
  45.   .is_not_pnm:
  46.         ret
  47.  
  48. endp
  49.  
  50. ;;================================================================================================;;
  51. proc img.decode.pnm _data, _length, _options ;////////////////////////////////////////////////////;;
  52. ;;------------------------------------------------------------------------------------------------;;
  53. ;? Decode data into image if it contains correctly formed raw data in pnm format                  ;;
  54. ;;------------------------------------------------------------------------------------------------;;
  55. ;> _data = raw data as read from file/stream                                                      ;;
  56. ;> _length = data length                                                                          ;;
  57. ;;------------------------------------------------------------------------------------------------;;
  58. ;< eax = 0 (error) or pointer to image                                                            ;;
  59. ;;================================================================================================;;
  60. locals
  61.         width                   rd      1
  62.         height                  rd      1
  63.         pnm_type                rd      1
  64.         data_type               rd      1       ; raw or ascii
  65.         maxval                  rd      1
  66.         retvalue                rd      1
  67. endl
  68.  
  69.         pusha
  70.  
  71.         mov     esi, [_data]
  72.         lodsw
  73.         cmp     ax, 'P1'
  74.         jne     @f
  75.         mov     [pnm_type], PNM_PBM
  76.         mov     [data_type], PNM_ASCII
  77.         jmp     .parse_header
  78.     @@:
  79.         cmp     ax, 'P2'
  80.         jne     @f
  81.         mov     [pnm_type], PNM_PGM
  82.         mov     [data_type], PNM_ASCII
  83.         jmp     .parse_header
  84.     @@:
  85.         cmp     ax, 'P3'
  86.         jne     @f
  87.         mov     [pnm_type], PNM_PPM
  88.         mov     [data_type], PNM_ASCII
  89.         jmp     .parse_header
  90.     @@:
  91.         cmp     ax, 'P4'
  92.         jne     @f
  93.         mov     [pnm_type], PNM_PBM
  94.         mov     [data_type], PNM_RAW
  95.         jmp     .parse_header
  96.     @@:
  97.         cmp     ax, 'P5'
  98.         jne     @f
  99.         mov     [pnm_type], PNM_PGM
  100.         mov     [data_type], PNM_RAW
  101.         jmp     .parse_header
  102.     @@:
  103.         cmp     ax, 'P6'
  104.         jne     @f
  105.         mov     [pnm_type], PNM_PPM
  106.         mov     [data_type], PNM_RAW
  107.         jmp     .parse_header
  108.     @@:
  109.  
  110.   .parse_header:
  111.         xor     eax, eax
  112.         mov     [width], eax
  113.         mov     [height], eax
  114.         mov     [maxval], eax
  115.  
  116.   .next_char:
  117.         lodsb
  118.         cmp     al, '#'
  119.         jb      .next_char
  120.         ja      .read_number
  121.   .comment:
  122.         mov     edi, esi
  123.         mov     al, 0x0A
  124.         mov     ecx, edi
  125.         sub     ecx, [_data]
  126.         neg     ecx
  127.         add     ecx, [_length]
  128.         repne   scasb
  129.         mov     esi, edi
  130.         jmp     .next_char
  131.  
  132.   .read_number:
  133.         sub     eax, 0x30
  134.         mov     ebx, eax
  135.     @@:
  136.         lodsb
  137.         cmp     al, '0'
  138.         jb      .number_done
  139.         sub     eax, 0x30
  140.         imul    ebx, 10
  141.         add     ebx, eax
  142.         jmp     @b
  143.  
  144.   .number_done:
  145.         cmp     [width], 0
  146.         jne     @f
  147.         mov     [width], ebx
  148.         jmp     .next_char
  149.     @@:
  150.         cmp     [height], 0
  151.         jne     @f
  152.         mov     [height], ebx
  153.         cmp     [pnm_type], PNM_PBM
  154.         je      .header_parsed
  155.         jmp     .next_char
  156.     @@:
  157.         mov     [maxval], ebx
  158.  
  159.   .header_parsed:
  160.  
  161.         cmp     [data_type], PNM_RAW
  162.         jne     @f
  163.         mov     ecx, [width]
  164.         imul    ecx, [height]
  165.         lea     eax, [ecx*3]
  166.         mov     edx, [_data]
  167.         add     edx, [_length]
  168.         sub     edx, esi
  169.         cmp     eax, edx
  170.         ja      .error
  171.     @@:
  172.  
  173.         mov     eax, [pnm_type]
  174.         cmp     eax, PNM_PBM
  175.         je      .pbm
  176.         cmp     eax, PNM_PGM
  177.         je      .pgm
  178.         cmp     eax, PNM_PPM
  179.         je      .ppm
  180.         jmp     .quit
  181.  
  182.  
  183. include 'pbm.asm'
  184. include 'pgm.asm'
  185. include 'ppm.asm'
  186.  
  187.   .error:
  188.         popa
  189.         xor     eax, eax
  190.         ret
  191.  
  192.   .quit:
  193.         popa
  194.         mov     eax, [retvalue]
  195.         ret
  196.  
  197. endp
  198.  
  199.  
  200.  
  201. ;;================================================================================================;;
  202. proc img.encode.pnm _img, _common, _specific ;////////////////////////////////////////////////////;;
  203. ;;------------------------------------------------------------------------------------------------;;
  204. ;? Encode image into raw data in pnm format                                                       ;;
  205. ;;------------------------------------------------------------------------------------------------;;
  206. ;> [_img]      = pointer to image                                                                 ;;
  207. ;> [_common]   = format independent options                                                       ;;
  208. ;> [_specific] = 0 / pointer to the structure of format specific options                          ;;
  209. ;;------------------------------------------------------------------------------------------------;;
  210. ;< eax = 0 / pointer to encoded data                                                              ;;
  211. ;< ecx = error code / the size of encoded data                                                    ;;
  212. ;;================================================================================================;;
  213. locals
  214.         encoded_file            rd 1
  215.         encoded_file_size       rd 1
  216.         encoded_data_size       rd 1
  217. endl
  218.         push    ebx
  219.  
  220.         mov     ebx, [_img]
  221.         mov     eax, [ebx + Image.Type]
  222.         cmp     eax, Image.bpp1
  223.         je      .pbm
  224.         cmp     eax, Image.bpp8g
  225.         je      .pgm
  226.         cmp     eax, Image.bpp24
  227.         je      .ppm
  228.         mov     ecx, LIBIMG_ERROR_BIT_DEPTH
  229.         jmp     .error
  230.   .pbm:
  231.         mov     ecx, [ebx + Image.Width]
  232.         add     ecx, 7
  233.         shr     ecx, 3
  234.         imul    ecx, [ebx + Image.Height]
  235.         mov     [encoded_data_size], ecx
  236.         add     ecx, (2 + 1) + (2 + pnm._.creator_comment.size + 1) + (5 + 1 + 5 + 1) + (3 + 1)
  237.         mov     [encoded_file_size], ecx
  238.         stdcall [mem.alloc], ecx
  239.         mov     [encoded_file], eax
  240.         test    eax, eax
  241.         jnz     @f
  242.         mov     ecx, LIBIMG_ERROR_OUT_OF_MEMORY
  243.         jmp     .error
  244.     @@:
  245.         mov     edi, eax
  246.         mov     ax, 'P4'
  247.         call    pnm._.write_header
  248.         mov     esi, [ebx + Image.Data]
  249.         mov     ecx, [encoded_data_size]
  250.         rep     movsb
  251.         mov     eax, [encoded_file]
  252.         mov     ecx, [encoded_file_size]
  253.         jmp     .quit
  254.        
  255.   .pgm:
  256.         mov     ecx, [ebx + Image.Width]
  257.         imul    ecx, [ebx + Image.Height]
  258.         mov     [encoded_data_size], ecx
  259.         add     ecx, (2 + 1) + (2 + pnm._.creator_comment.size + 1) + (5 + 1 + 5 + 1) + (3 + 1)
  260.         mov     [encoded_file_size], ecx
  261.         stdcall [mem.alloc], ecx
  262.         mov     [encoded_file], eax
  263.         test    eax, eax
  264.         jnz     @f
  265.         mov     ecx, LIBIMG_ERROR_OUT_OF_MEMORY
  266.         jmp     .error
  267.     @@:
  268.         mov     edi, eax
  269.         mov     ax, 'P5'
  270.         call    pnm._.write_header
  271.         mov     dword[edi], '255 '
  272.         add     edi, 3
  273.         mov     byte[edi], 0x0A
  274.         add     edi, 1
  275.         mov     esi, [ebx + Image.Data]
  276.         mov     ecx, [encoded_data_size]
  277.         rep     movsb
  278.         mov     eax, [encoded_file]
  279.         mov     ecx, [encoded_file_size]
  280.         jmp     .quit
  281.  
  282.   .ppm:
  283.         mov     ecx, [ebx + Image.Width]
  284.         imul    ecx, [ebx + Image.Height]
  285.         lea     ecx, [ecx*3]
  286.         mov     [encoded_data_size], ecx
  287.         add     ecx, (2 + 1) + (2 + pnm._.creator_comment.size + 1) + (5 + 1 + 5 + 1) + (3 + 1)
  288.         mov     [encoded_file_size], ecx
  289.         stdcall [mem.alloc], ecx
  290.         mov     [encoded_file], eax
  291.         test    eax, eax
  292.         jnz     @f
  293.         mov     ecx, LIBIMG_ERROR_OUT_OF_MEMORY
  294.         jmp     .error
  295.     @@:
  296.         mov     edi, eax
  297.         mov     ax, 'P6'
  298.         call    pnm._.write_header
  299.         mov     dword[edi], '255 '
  300.         add     edi, 3
  301.         mov     byte[edi], 0x0A
  302.         add     edi, 1
  303.         mov     esi, [ebx + Image.Data]
  304.         mov     ecx, [ebx + Image.Width]
  305.         imul    ecx, [ebx + Image.Height]
  306.     @@:
  307.         lodsb
  308.         mov     byte[edi+2], al
  309.         lodsb
  310.         mov     byte[edi+1], al
  311.         movsb
  312.         add     edi, 2
  313.         dec     ecx
  314.         jnz     @b
  315.         mov     eax, [encoded_file]
  316.         mov     ecx, [encoded_file_size]
  317.         jmp     .quit
  318.  
  319.   .error:
  320.         xor     eax, eax
  321.   .quit:
  322.         pop     ebx
  323.         ret
  324. endp
  325.  
  326.  
  327. ;;================================================================================================;;
  328. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  329. ;;================================================================================================;;
  330. ;! Below are private procs you should never call directly from your code                          ;;
  331. ;;================================================================================================;;
  332. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  333. ;;================================================================================================;;
  334. proc    pnm._.get_number
  335.         sub     eax, '0'
  336.         mov     ebx, eax
  337.     @@:
  338.         lodsb
  339.         cmp     al, '0'
  340.         jb      .quit
  341.         sub     eax, '0'
  342.         lea     eax, [ebx*8 + eax]
  343.         lea     ebx, [ebx*2 + eax]
  344. ;       imul    ebx, 10
  345. ;       add     ebx, eax
  346.         jmp     @b
  347.   .quit:
  348.         ret
  349. endp
  350.  
  351.  
  352. proc    pnm._.write_header
  353.         stosw
  354.         mov     byte[edi], 0x0A
  355.         add     edi, 1
  356.         mov     word[edi], '# '
  357.         add     edi, 2
  358.         mov     esi, pnm._.creator_comment
  359.         mov     ecx, pnm._.creator_comment.size
  360.         rep     movsb
  361.         mov     byte[edi], 0x0A
  362.         add     edi, 1
  363.  
  364.         push    edi
  365.         mov     al, ' '
  366.         mov     ecx, (5 + 1 + 5)
  367.         rep     stosb
  368.         pop     edi
  369.         push    edi
  370.         add     edi, 4
  371.         mov     eax, [ebx + Image.Width]
  372.         mov     ecx, 10
  373.   .write_width:
  374.         xor     edx, edx
  375.         div     cx
  376.         add     dl, '0'
  377.         mov     byte[edi], dl
  378.         dec     edi
  379.         test    ax, ax
  380.         jnz     .write_width
  381.         mov     eax, [ebx + Image.Height]
  382.         pop     edi
  383.         push    edi
  384.         add     edi, 10
  385.   .write_height:
  386.         xor     edx, edx
  387.         div     cx
  388.         add     dl, '0'
  389.         mov     byte[edi], dl
  390.         dec     edi
  391.         test    ax, ax
  392.         jnz     .write_height
  393.         pop     edi
  394.         add     edi, 11
  395.         mov     byte[edi], 0x0A
  396.         add     edi, 1
  397.         ret
  398. endp
  399. ;;================================================================================================;;
  400. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  401. ;;================================================================================================;;
  402. ;! Below is private data you should never use directly from your code                             ;;
  403. ;;================================================================================================;;
  404. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  405. ;;================================================================================================;;
  406.  
  407. sz pnm._.creator_comment ,'CREATOR: KolibriOS / libimg'
  408.  
  409.