Subversion Repositories Kolibri OS

Rev

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

  1. ;;================================================================================================;;
  2. ;;//// tiff.asm //// (c) dunkaist, 2011-2013 /////////////////////////////////////////////////////;;
  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 'tiff.inc'
  21.  
  22. ;;================================================================================================;;
  23. proc img.is.tiff _data, _length ;/////////////////////////////////////////////////////////////////;;
  24. ;;------------------------------------------------------------------------------------------------;;
  25. ;? Determine if raw data could be decoded (is in tiff format)                                     ;;
  26. ;;------------------------------------------------------------------------------------------------;;
  27. ;> _data = raw data as read from file/stream                                                      ;;
  28. ;> _length = data length                                                                          ;;
  29. ;;------------------------------------------------------------------------------------------------;;
  30. ;< eax = false / true                                                                             ;;
  31. ;;================================================================================================;;
  32.  
  33.         push    esi
  34.  
  35.         mov     esi, [_data]
  36.         lodsw
  37.         cmp     ax, word 'II'
  38.         je      .little_endian
  39.         cmp     ax, word 'MM'
  40.         je      .big_endian
  41.         jmp     .is_not_tiff
  42.  
  43.   .little_endian:
  44.         lodsw
  45.         cmp     ax, 0x002A
  46.         je      .is_tiff
  47.         jmp     .is_not_tiff
  48.  
  49.   .big_endian:
  50.         lodsw
  51.         cmp     ax, 0x2A00
  52.         je      .is_tiff
  53.  
  54.   .is_not_tiff:
  55.         pop     esi
  56.         xor     eax, eax
  57.         ret
  58.  
  59.   .is_tiff:
  60.         pop     esi
  61.         xor     eax, eax
  62.         inc     eax
  63.         ret
  64. endp
  65.  
  66. ;;================================================================================================;;
  67. proc img.decode.tiff _data, _length, _options ;///////////////////////////////////////////////////;;
  68. ;;------------------------------------------------------------------------------------------------;;
  69. ;? Decode data into image if it contains correctly formed raw data in tiff format                 ;;
  70. ;;------------------------------------------------------------------------------------------------;;
  71. ;> _data = raw data as read from file/stream                                                      ;;
  72. ;> _length = data length                                                                          ;;
  73. ;;------------------------------------------------------------------------------------------------;;
  74. ;< eax = 0 (error) or pointer to image                                                            ;;
  75. ;;================================================================================================;;
  76. locals
  77.         _endianness             rd 1            ; 0 stands for LE, otherwise BE
  78.         retvalue                rd 1            ; 0 (error) or pointer to image
  79. endl
  80.  
  81.         push    ebx edx esi edi
  82.  
  83.         mov     esi, [_data]
  84.         lodsw
  85.         mov     [_endianness], 0
  86.         cmp     ax, word 'II'
  87.         seta    byte[_endianness]
  88.  
  89.         lodsw_
  90.         lodsd_
  91.     @@:
  92.         stdcall tiff._.parse_IFD, [_data], eax, [_endianness]
  93.         mov     ebx, eax
  94.         mov     [retvalue], eax
  95.         lodsd_
  96.         test    eax, eax
  97. ;       jnz     @b
  98.  
  99.  
  100.   .quit:
  101.         mov     eax, [retvalue]
  102.         pop     edi esi edx ebx
  103.         ret
  104. endp
  105.  
  106.  
  107. ;;================================================================================================;;
  108. proc img.encode.tiff _img, _p_length, _options ;//////////////////////////////////////////////////;;
  109. ;;------------------------------------------------------------------------------------------------;;
  110. ;? Encode image into raw data in tiff format                                                      ;;
  111. ;;------------------------------------------------------------------------------------------------;;
  112. ;> _img = pointer to image                                                                        ;;
  113. ;;------------------------------------------------------------------------------------------------;;
  114. ;< eax = 0 (error) or pointer to encoded data                                                     ;;
  115. ;< _p_length = encoded data length                                                                ;;
  116. ;;================================================================================================;;
  117.         xor     eax, eax
  118.         ret
  119. endp
  120.  
  121.  
  122. ;;================================================================================================;;
  123. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  124. ;;================================================================================================;;
  125. ;! Below are private procs you should never call directly from your code                          ;;
  126. ;;================================================================================================;;
  127. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  128. ;;================================================================================================;;
  129. proc tiff._.parse_IFD _data, _IFD, _endianness
  130. locals
  131.         extended                rd      1
  132.         retvalue                rd      1
  133.         decompress              rd      1
  134. endl
  135.         push    ebx edx edi
  136.         mov     [retvalue], 0
  137.  
  138.         invoke  mem.alloc, sizeof.tiff_extra
  139.         test    eax, eax
  140.         jz      .quit
  141.         mov     [extended], eax
  142.         mov     ebx, eax
  143.         mov     edi, eax
  144.         mov     ecx, sizeof.tiff_extra/4
  145.         xor     eax, eax
  146.         rep     stosd
  147.  
  148.         mov     esi, [_IFD]
  149.         add     esi, [_data]
  150.         lodsw_
  151.         movzx   ecx, ax
  152.     @@:
  153.         push    ecx
  154.         stdcall tiff._.parse_IFDE, [_data], [_endianness]
  155.         pop     ecx
  156.         dec     ecx
  157.         jnz     @b
  158.  
  159.         call    tiff._.define_image_type
  160.  
  161.         stdcall img.create, [ebx + tiff_extra.image_width], [ebx + tiff_extra.image_height], eax
  162.         test    eax, eax
  163.         jz      .quit
  164.         mov     [retvalue], eax
  165.         mov     edx, eax
  166.         mov     [edx + Image.Extended], ebx
  167.  
  168.         cmp     [ebx+tiff_extra.compression], TIFF.COMPRESSION.UNCOMPRESSED
  169.         jne     @f
  170.         mov     [decompress], tiff._.decompress.uncompressed
  171.         jmp     .decompressor_defined
  172.     @@:
  173.         cmp     [ebx + tiff_extra.compression], TIFF.COMPRESSION.PACKBITS
  174.         jne     @f
  175.         mov     [decompress], tiff._.decompress.packbits
  176.         jmp     .decompressor_defined
  177.     @@:
  178.         cmp     [ebx + tiff_extra.compression], TIFF.COMPRESSION.LZW
  179.         jne     @f
  180.         mov     [decompress], tiff._.decompress.lzw
  181.         jmp     .decompressor_defined
  182.     @@:
  183.         cmp     [ebx + tiff_extra.compression], TIFF.COMPRESSION.CCITT1D
  184.         jne     @f
  185.         mov     [decompress], tiff._.decompress.ccitt1d
  186.         jmp     .decompressor_defined
  187.     @@:
  188.  
  189.         mov     [decompress], 0
  190.         jmp     .quit
  191.   .decompressor_defined:
  192.  
  193.         push    esi             ; fixme!!
  194.  
  195.         mov     ecx, [edx + Image.Type]
  196.         cmp     ecx, Image.bpp8i
  197.         je      .bpp8i
  198.         cmp     ecx, Image.bpp24
  199.         je      .bpp24
  200.         cmp     ecx, Image.bpp32
  201.         je      .bpp32
  202.         cmp     ecx, Image.bpp16
  203.         je      .bpp16
  204.         cmp     ecx, Image.bpp1
  205.         je      .bpp1
  206.         cmp     ecx, Image.bpp8g
  207.         je      .bpp8g
  208.         cmp     ecx, Image.bpp8a
  209.         je      .bpp8a
  210.         cmp     ecx, Image.bpp2i
  211.         je      .bpp2i
  212.         cmp     ecx, Image.bpp4i
  213.         je      .bpp4i
  214.         jmp     .quit
  215. ;error report!!
  216.  
  217.   .bpp1:
  218.   .bpp1.palette:
  219.         mov     edi, [edx+Image.Palette]
  220.         cmp     [ebx + tiff_extra.photometric], TIFF.PHOTOMETRIC.BLACK_IS_ZERO
  221.         jne     .bpp1.white_is_zero
  222.   .bpp1.black_is_zero:
  223.         mov     [edi], dword 0xff000000
  224.         mov     [edi + 4], dword 0xffffffff
  225.         jmp     .common
  226.   .bpp1.white_is_zero:
  227.         mov     [edi], dword 0xffffffff
  228.         mov     [edi + 4], dword 0xff000000
  229.         jmp     .common
  230.  
  231.   .bpp2i:
  232.         stdcall tiff._.get_palette, 1 SHL 2, [_endianness]
  233.         jmp     .common
  234.  
  235.   .bpp4i:
  236.         stdcall tiff._.get_palette, 1 SHL 4, [_endianness]
  237.         jmp     .common
  238.  
  239.   .bpp8i:
  240.         stdcall tiff._.get_palette, 1 SHL 8, [_endianness]
  241.         jmp     .common
  242.   .bpp8g:
  243.         jmp     .common
  244.  
  245.   .bpp8a:
  246.         jmp     .common
  247.  
  248.   .bpp16:
  249.         jmp     .common
  250.  
  251.   .bpp24:
  252.         jmp     .common
  253.  
  254.   .bpp32:
  255.         jmp     .common
  256.  
  257.  
  258.   .common:
  259.         mov     edi, [edx+Image.Data]
  260.         mov     esi, [ebx+tiff_extra.strip_offsets]
  261.         mov     edx, [ebx+tiff_extra.strip_byte_counts]
  262.  
  263.  
  264.         cmp     [ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  265.         jne     .l_x
  266.         cmp     [ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  267.         jne     .s_l
  268.         jmp     .s_s
  269.   .l_x: cmp     [ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  270.         jne     .l_l
  271.         jmp     .l_s
  272.  
  273.   .s_s:
  274.         xor     eax, eax
  275.         lodsw_
  276.         push    esi
  277.         mov     esi, eax
  278.         add     esi, [_data]
  279.         xor     ecx, ecx
  280.         mov     cx, word[edx]
  281.         test    [_endianness], 1
  282.         jz      @f
  283.         xchg    cl, ch
  284.     @@:
  285.         add     edx, 2
  286.         stdcall [decompress], [retvalue]
  287.         pop     esi
  288.         dec     [ebx + tiff_extra.offsets_number]
  289.         jnz     .s_s
  290.         jmp     .decoded
  291.  
  292.   .s_l:
  293.         xor     eax, eax
  294.         lodsw_
  295.         push    esi
  296.         mov     esi, eax
  297.         add     esi, [_data]
  298.         mov     ecx, [edx]
  299.         test    [_endianness], 1
  300.         jz      @f
  301.         bswap   ecx
  302.     @@:
  303.         add     edx, 4
  304.         stdcall [decompress], [retvalue]
  305.         pop     esi
  306.         dec     [ebx + tiff_extra.offsets_number]
  307.         jnz     .s_l
  308.         jmp     .decoded
  309.  
  310.   .l_s:
  311.         lodsd_
  312.         push    esi
  313.         mov     esi, eax
  314.         add     esi, [_data]
  315.         xor     ecx, ecx
  316.         mov     cx, word[edx]
  317.         test    [_endianness], 1
  318.         jz      @f
  319.         xchg    cl, ch
  320.     @@:
  321.         add     edx, 2
  322.         stdcall [decompress], [retvalue]
  323.         pop     esi
  324.         dec     [ebx + tiff_extra.offsets_number]
  325.         jnz     .l_s
  326.         jmp     .decoded
  327.  
  328.   .l_l:
  329.         lodsd_
  330.         push    esi
  331.         mov     esi, eax
  332.         add     esi, [_data]
  333.         mov     ecx, [edx]
  334.         test    [_endianness], 1
  335.         jz      @f
  336.         bswap   ecx
  337.     @@:
  338.         add     edx, 4
  339.         stdcall [decompress], [retvalue]
  340.         pop     esi
  341.         dec     [ebx + tiff_extra.offsets_number]
  342.         jnz     .l_l
  343.         jmp     .decoded
  344.  
  345.  
  346.   .decoded:
  347.         cmp     [ebx + tiff_extra.planar_configuration], TIFF.PLANAR.PLANAR
  348.         jne     .post.rgb_bgr
  349.         stdcall tiff._.planar_to_separate, [retvalue]
  350.   .post.rgb_bgr:
  351.         cmp     [ebx + tiff_extra.samples_per_pixel], 3
  352.         jne     .post.rgba_bgra
  353.         mov     eax, [retvalue]
  354.         mov     esi, [eax + Image.Data]
  355.         mov     edi, [eax + Image.Data]
  356.         mov     ecx, [eax + Image.Width]
  357.         imul    ecx, [eax + Image.Height]
  358.     @@:
  359.         lodsw
  360.         movsb
  361.         mov     byte[esi - 1], al
  362.         add     edi, 2
  363.         dec     ecx
  364.         jnz     @b
  365.  
  366.   .post.rgba_bgra:
  367.         cmp     [ebx + tiff_extra.samples_per_pixel], 4
  368.         jne     .post.bpp8a_to_bpp8g
  369.         mov     eax, [retvalue]
  370.         mov     esi, [eax + Image.Data]
  371.         mov     edi, [eax + Image.Data]
  372.         mov     ecx, [eax + Image.Width]
  373.         imul    ecx, [eax + Image.Height]
  374.     @@:
  375.         lodsw
  376.         movsb
  377.         mov     byte[esi - 1], al
  378.         add     edi, 3
  379.         add     esi, 1
  380.         dec     ecx
  381.         jnz     @b
  382.  
  383.   .post.bpp8a_to_bpp8g:
  384.         mov     eax, [retvalue]
  385.         cmp     [eax + Image.Type], Image.bpp8a
  386.         jne     .post.predictor
  387.         mov     ebx, [retvalue]
  388.         stdcall tiff._.pack_8a, ebx
  389.         mov     [ebx + Image.Type], Image.bpp8g
  390.  
  391.   .post.predictor:
  392.         cmp     [ebx + tiff_extra.predictor], 2         ; Horizontal differencing
  393.         jne     .post.end
  394.         cmp     [ebx + tiff_extra.image_width], 1
  395.         je      .post.end
  396.         push    ebx
  397.         mov     edi, [ebx + tiff_extra.samples_per_pixel]
  398.         mov     edx, edi
  399.         mov     ebx, [retvalue]
  400.   .post.predictor.plane:
  401.         mov     esi, [ebx + Image.Data]
  402.         sub     esi, 1
  403.         add     esi, edx
  404.         mov     ecx, [ebx + Image.Height]
  405.   .post.predictor.line:
  406.         push    ecx
  407.         mov     ecx, [ebx + Image.Width]
  408.         sub     ecx, 1
  409.         mov     ah, byte[esi]
  410.         add     esi, edi
  411.     @@:
  412.         mov     al, byte[esi]
  413.         add     al, ah
  414.         mov     byte[esi], al
  415.         add     esi, edi
  416.         shl     eax, 8
  417.         dec     ecx
  418.         jnz     @b
  419.         pop     ecx
  420.         dec     ecx
  421.         jnz     .post.predictor.line
  422.         dec     edx
  423.         jnz     .post.predictor.plane
  424.         pop     ebx
  425.  
  426.   .post.end:
  427.  
  428.   .pop_quit:
  429.         pop     esi
  430.   .quit:
  431.         pop     edi edx ebx
  432.         mov     eax, [retvalue]
  433.         ret
  434. endp
  435.  
  436. proc tiff._.parse_IFDE _data, _endianness
  437.  
  438.         push    ebx edx edi
  439.  
  440.         lodsw_
  441.         mov     edx, tiff.IFDE_tag_table.begin
  442.         mov     ecx, (tiff.IFDE_tag_table.end-tiff.IFDE_tag_table.begin)/8
  443.   .tag:
  444.         cmp     ax, word[edx]
  445.         jne     @f
  446.         lodsw_
  447.         jmp     dword[edx + 4]
  448.     @@:
  449.         add     edx, 8
  450.         dec     ecx
  451.         jnz     .tag
  452.   .tag_default:                                         ; unknown/unsupported/unimportant
  453.         lodsw
  454.         lodsd
  455.         lodsd
  456.         jmp     .quit                                   ; just skip it
  457.  
  458.   .tag_100:                                             ; ImageWidth
  459.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  460.         jne     @f
  461.         lodsd
  462.         xor     eax, eax
  463.         lodsw_
  464.         mov     [ebx + tiff_extra.image_width], eax
  465.         lodsw
  466.         jmp     .quit
  467.     @@:
  468.         cmp     ax, TIFF.IFDE_TYPE.LONG
  469.         jne     @f
  470.         lodsd
  471.         lodsd_
  472.         mov     [ebx + tiff_extra.image_width], eax
  473.         jmp     .quit
  474.     @@:
  475.         jmp     .quit
  476.  
  477.   .tag_101:                                             ; ImageHeight
  478.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  479.         jne     @f
  480.         lodsd
  481.         xor     eax, eax
  482.         lodsw_
  483.         mov     [ebx + tiff_extra.image_height], eax
  484.         lodsw
  485.         jmp     .quit
  486.     @@:
  487.         cmp     ax, TIFF.IFDE_TYPE.LONG
  488.         jne     @f
  489.         lodsd
  490.         lodsd_
  491.         mov     [ebx + tiff_extra.image_height], eax
  492.         jmp     .quit
  493.     @@:
  494.         jmp     .quit
  495.  
  496.   .tag_102:                                             ; BitsPerSample
  497.         lodsd_
  498.         imul    eax, TIFF.IFDE_TYPE_LENGTH.SHORT
  499.         cmp     eax, 4
  500.         ja      @f
  501.         xor     eax, eax
  502.         lodsw_
  503.         mov     [ebx + tiff_extra.bits_per_sample], eax
  504.         lodsw
  505.         jmp     .quit
  506.     @@:
  507.         lodsd_
  508.         add     eax, [_data]
  509.         push    esi
  510.         mov     esi, eax
  511.         xor     eax, eax
  512.         lodsw_
  513.         pop     esi
  514.         mov     [ebx + tiff_extra.bits_per_sample], eax
  515.         jmp     .quit
  516.  
  517.   .tag_103:                                             ; Compression
  518.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  519.         jne     @f
  520.         lodsd
  521.         xor     eax, eax
  522.         lodsw_
  523.         mov     [ebx + tiff_extra.compression], eax
  524.         lodsw
  525.         jmp     .quit
  526.     @@:
  527.         jmp     .quit
  528.  
  529.   .tag_106:                                             ; PhotometricInterpretation
  530.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  531.         jne     @f
  532.         lodsd
  533.         xor     eax, eax
  534.         lodsw_
  535.         mov     [ebx + tiff_extra.photometric], eax
  536.         lodsw
  537.         jmp     .quit
  538.     @@:
  539.  
  540.         jmp     .quit
  541.  
  542.   .tag_111:                                             ; StripOffsets
  543.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  544.         jne     @f
  545.         mov     [ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  546.         jmp     .tag_111.common
  547.     @@:
  548.         mov     [ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.LONG
  549.   .tag_111.common:
  550.         lodsd_
  551.         mov     [ebx + tiff_extra.offsets_number], eax
  552.         imul    eax, [ebx+tiff_extra.strip_offsets_length]
  553.         cmp     eax, 4
  554.         ja      @f
  555.         mov     [ebx + tiff_extra.strip_offsets], esi
  556.         lodsd
  557.         jmp     .quit
  558.     @@:
  559.         lodsd_
  560.         add     eax, [_data]
  561.         mov     [ebx + tiff_extra.strip_offsets], eax
  562.         jmp     .quit
  563.  
  564.   .tag_115:                                             ; SamplesPerPixel
  565.         lodsd_
  566.         imul    eax, TIFF.IFDE_TYPE_LENGTH.SHORT
  567.         cmp     eax, 4
  568.         ja      @f
  569.         xor     eax, eax
  570.         lodsw_
  571.         mov     [ebx + tiff_extra.samples_per_pixel], eax
  572.         lodsw
  573.         jmp     .quit
  574.     @@:
  575.         lodsd_
  576.         add     eax, [_data]
  577.         movzx   eax, word[eax]
  578.         jmp     .quit
  579.  
  580.   .tag_116:                                             ; RowsPerStrip
  581.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  582.         jne     @f
  583.         lodsd
  584.         xor     eax, eax
  585.         lodsw_
  586.         mov     [ebx + tiff_extra.rows_per_strip], eax
  587.         lodsw
  588.         jmp     .quit
  589.     @@:
  590.         lodsd
  591.         lodsd_
  592.         mov     [ebx + tiff_extra.rows_per_strip], eax
  593.         jmp     .quit
  594.  
  595.   .tag_117:                                             ; StripByteCounts
  596.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  597.         jne     @f
  598.         mov     [ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  599.         jmp     .tag_117.common
  600.     @@:
  601.         mov     [ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.LONG
  602.   .tag_117.common:
  603.         lodsd_
  604.         imul    eax, [ebx + tiff_extra.strip_byte_counts_length]
  605.         cmp     eax, 4
  606.         ja      @f
  607.         mov     [ebx + tiff_extra.strip_byte_counts], esi
  608.         lodsd
  609.         jmp     .quit
  610.     @@:
  611.         lodsd_
  612.         add     eax, [_data]
  613.         mov     [ebx + tiff_extra.strip_byte_counts], eax
  614.         jmp     .quit
  615.  
  616.   .tag_11c:                                             ; Planar configuration
  617.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  618.         jne     @f
  619.         lodsd
  620.         xor     eax, eax
  621.         lodsw_
  622.         mov     [ebx + tiff_extra.planar_configuration], eax
  623.         lodsw
  624.     @@:
  625.         jmp     .quit
  626.  
  627.  
  628.   .tag_13d:                                             ; Predictor
  629.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  630.         jne     @f
  631.         lodsd
  632.         xor     eax, eax
  633.         lodsw_
  634.         mov     [ebx + tiff_extra.predictor], eax
  635.         lodsw
  636.     @@:
  637.         jmp     .quit
  638.  
  639.   .tag_140:                                             ; ColorMap
  640.         lodsd
  641.         lodsd_
  642.         add     eax, [_data]
  643.         mov     [ebx + tiff_extra.palette], eax
  644.         jmp     .quit
  645.   .tag_152:                                             ; ExtraSamples
  646.         mov     [ebx + tiff_extra.extra_samples], esi
  647.         mov     ecx, [ebx + tiff_extra.extra_samples_number]
  648.         rep     lodsw   ; ignored
  649.         jmp     .quit
  650.  
  651.   .quit:
  652.         pop     edi edx ebx
  653.         ret
  654. endp
  655.  
  656.  
  657. proc tiff._.define_image_type
  658.  
  659.         xor     eax, eax
  660.  
  661.         cmp     [ebx + tiff_extra.photometric], TIFF.PHOTOMETRIC.RGB
  662.         jne     .palette_bilevel_grayscale
  663.         mov     eax, -3
  664.         add     eax, [ebx + tiff_extra.samples_per_pixel]
  665.         mov     [ebx + tiff_extra.extra_samples_number], eax
  666.         dec     eax
  667.         jns     @f
  668.         mov     eax, Image.bpp24
  669.         jmp     .quit
  670.     @@:
  671.         dec     eax
  672.         jns     @f
  673.         mov     eax, Image.bpp32
  674. ;       mov     [ebx + tiff_extra.extra_samples_number], 0
  675.         jmp     .quit
  676.     @@:
  677.   .palette_bilevel_grayscale:
  678.         cmp     [ebx + tiff_extra.palette], 0
  679.         je      .bilevel_grayscale
  680.         cmp     [ebx + tiff_extra.bits_per_sample], 2
  681.         jg      @f
  682.         mov     eax, Image.bpp2i
  683.         jmp     .quit
  684.     @@:
  685.         cmp     [ebx + tiff_extra.bits_per_sample], 4
  686.         jg      @f
  687.         mov     eax, Image.bpp4i
  688.         jmp     .quit
  689.     @@:
  690.         cmp     [ebx + tiff_extra.bits_per_sample], 8
  691.         jne     @f
  692.         mov     eax, Image.bpp8i
  693.         jmp     .quit
  694.     @@:
  695.         jmp     .quit
  696.   .bilevel_grayscale:
  697.         cmp     [ebx + tiff_extra.bits_per_sample], 1
  698.         jg      .grayscale
  699.         mov     eax, Image.bpp1
  700.         jmp     .quit
  701.   .grayscale:
  702.         cmp     [ebx + tiff_extra.bits_per_sample], 8
  703.         jne     .quit
  704.         cmp     [ebx + tiff_extra.samples_per_pixel], 1
  705.         jne     @f
  706.         mov     eax, Image.bpp8g
  707.         jmp     .quit
  708.     @@:
  709.         mov     eax, Image.bpp8a
  710.         jmp     .quit
  711.   .quit:
  712.         ret
  713. endp
  714.  
  715.  
  716. proc tiff._.decompress.uncompressed _image
  717.  
  718.         rep     movsb
  719.         ret
  720. endp
  721.  
  722.  
  723. proc tiff._.decompress.packbits _image
  724.  
  725.         push    edx
  726.  
  727.         mov     edx, ecx
  728.  
  729.   .decode:
  730.         lodsb
  731.         dec     edx
  732.         cmp     al, 0x80
  733.         jb      .different
  734.         jg      .identical
  735.         test    edx, edx
  736.         jz      .quit
  737.         jmp     .decode
  738.  
  739.   .identical:
  740.         neg     al
  741.         inc     al
  742.         movzx   ecx, al
  743.         dec     edx
  744.         lodsb
  745.         rep     stosb
  746.         test    edx, edx
  747.         jnz     .decode
  748.         jmp     .quit
  749.  
  750.   .different:
  751.         movzx   ecx, al
  752.         inc     ecx
  753.         sub     edx, ecx
  754.         rep     movsb
  755.         test    edx, edx
  756.         jnz     .decode
  757.  
  758.   .quit:
  759.         pop     edx
  760.         ret
  761. endp
  762.  
  763.  
  764. proc    tiff._.decompress.ccitt1d _image
  765. locals
  766.         current_tree            rd      1
  767.         old_tree                rd      1
  768.         width                   rd      1
  769.         height                  rd      1
  770.         width_left              rd      1
  771.         is_makeup               rd      1
  772. endl
  773.         push    ebx ecx edx esi
  774.         mov     [is_makeup], 0
  775.  
  776.         mov     ebx, [_image]
  777.         push    [ebx + Image.Height]
  778.         pop     [height]
  779.         push    [ebx + Image.Width]
  780.         pop     [width]
  781.  
  782.         mov     edx, esi
  783.   .next_scanline:
  784.         push    [width]
  785.         pop     [width_left]
  786.         dec     [height]
  787.         js      .error
  788.         mov     [current_tree], tiff._.huffman_tree_white.begin
  789.         mov     [old_tree], tiff._.huffman_tree_black.begin
  790.         mov     ebx, 0
  791.         mov     ecx, 8
  792.   .next_run:
  793.         mov     esi, [current_tree]
  794.   .branch:
  795.         lodsd
  796.         btr     eax, 31
  797.         jnc     .not_a_leaf
  798.         cmp     eax, 63
  799.         seta    byte[is_makeup]
  800.         ja      @f
  801.         push    [current_tree]
  802.         push    [old_tree]
  803.         pop     [current_tree]
  804.         pop     [old_tree]
  805.     @@:
  806.         stdcall tiff._.write_run, [width_left], [current_tree]
  807.         mov     [width_left], eax
  808.         test    byte[is_makeup], 0x01
  809.         jnz     .next_run
  810.         test    eax, eax
  811.         jnz     .next_run
  812.         jmp     .next_scanline
  813.   .not_a_leaf:
  814.         test    bh, bh
  815.         jnz     @f
  816.         mov     bl, byte[edx]
  817.         inc     edx
  818.         mov     bh, 8
  819.     @@:
  820.         test    al, 0x02
  821.         jz      .not_a_corner
  822.         dec     bh
  823.         sal     bl, 1
  824.         lahf
  825.         and     ah, 0x03
  826.         cmp     al, ah
  827.         jne     .error
  828.         mov     esi, [esi]
  829.         jmp     .branch
  830.   .not_a_corner:
  831.         lodsd
  832.         dec     bh
  833.         sal     bl, 1
  834.         jc      .branch
  835.         mov     esi, eax
  836.         jmp     .branch
  837.   .error:
  838.   .quit:
  839.         pop     esi edx ecx ebx
  840.         ret
  841. endp
  842.  
  843.  
  844. proc tiff._.decompress.lzw _image
  845. locals
  846.         cur_shift               rd 1    ; 9 -- 12
  847.         shift_counter           rd 1    ; how many shifts of current length remained
  848.         bits_left               rd 1    ; in current byte ( pointed to by [esi] )
  849.         table                   rd 1
  850.         table_size              rd 1    ; the number of entries
  851.         old_code                rd 1
  852.         next_table_entry        rd 1    ; where to place new entry
  853. endl
  854.         push    ebx ecx edx esi
  855.  
  856.         mov     [table], 0
  857.         mov     [bits_left], 8
  858.         mov     [cur_shift], 9
  859.  
  860.   .begin:
  861.  
  862.  ; .getnextcode:
  863.         xor     eax, eax
  864.         mov     edx, [cur_shift]
  865.  
  866.         lodsb
  867.         mov     ecx, [bits_left]
  868.         mov     ch, cl
  869.         neg     cl
  870.         add     cl, 8
  871.         shl     al, cl
  872.         mov     cl, ch
  873.         shl     eax, cl
  874.         sub     edx, [bits_left]
  875.         ; second_byte
  876.         cmp     edx, 8
  877.         je      .enough_zero
  878.         jb      .enough_nonzero
  879.         sub     edx, 8
  880.         lodsb
  881.         shl     eax, 8
  882.         jmp     .third_byte
  883.   .enough_zero:
  884.         mov     [bits_left], 8
  885.         lodsb
  886.         jmp     .code_done
  887.   .enough_nonzero:
  888.         mov     al, byte[esi]
  889.         neg     edx
  890.         add     edx, 8
  891.         mov     ecx, edx
  892.         mov     [bits_left], edx
  893.         shr     eax, cl
  894.         jmp     .code_done
  895.   .third_byte:
  896.         mov     al, byte[esi]
  897.         neg     edx
  898.         add     edx, 8
  899.         mov     ecx, edx
  900.         mov     [bits_left], edx
  901.         shr     eax, cl
  902.   .code_done:
  903.  
  904.  
  905.         mov     ebx, eax
  906.         cmp     ebx, 0x101      ; end of information
  907.         je      .quit
  908.         cmp     ebx, 0x100      ; clear code
  909.         jne     .no_clear_code
  910.  
  911.         cmp     [table], 0
  912.         jne     @f
  913.         invoke  mem.alloc, 256 + 63488  ; 256 + (2^8 + 2^9 + 2^10 + 2^11 + 2^12)*(4+4)
  914.         test    eax, eax
  915.         jz      .quit
  916.         mov     [table], eax
  917.     @@:
  918.         mov     eax, [table]
  919.         mov     [next_table_entry], eax
  920.         add     [next_table_entry], 256 + (256*8) + 2*8
  921.         mov     [cur_shift], 9
  922.         mov     [shift_counter], 256-3  ; clear code, end of information, why -3?
  923.         mov     [table_size], 257
  924.  
  925.         push    edi
  926.         mov     ecx, 256
  927.         mov     edi, [table]
  928.         mov     ebx, edi
  929.         add     edi, 256
  930.         mov     eax, 0
  931.     @@:
  932.         mov     byte[ebx], al
  933.         mov     [edi], ebx
  934.         add     edi, 4
  935.         add     ebx, 1
  936.         add     eax, 1
  937.         mov     [edi], dword 1
  938.         add     edi, 4
  939.         dec     ecx
  940.         jnz     @b
  941.         pop     edi
  942. ;  .getnextcode:
  943.         xor     eax, eax
  944.         mov     edx, [cur_shift]
  945.  
  946.         lodsb
  947.         mov     ecx, [bits_left]
  948.         mov     ch, cl
  949.         neg     cl
  950.         add     cl, 8
  951.         shl     al, cl
  952.         mov     cl, ch
  953.         shl     eax, cl
  954.         sub     edx, [bits_left]
  955.         ; second_byte
  956.         cmp     edx, 8
  957.         je      .enough_zero2
  958.         jb      .enough_nonzero2
  959.         sub     edx, 8
  960.         lodsb
  961.         shl     eax, 8
  962.         jmp     .third_byte2
  963.   .enough_zero2:
  964.         mov     [bits_left], 8
  965.         lodsb
  966.         jmp     .code_done2
  967.   .enough_nonzero2:
  968.         mov     al, byte[esi]
  969.         neg     edx
  970.         add     edx, 8
  971.         mov     ecx, edx
  972.         mov     [bits_left], edx
  973.         shr     eax, cl
  974.         jmp     .code_done2
  975.   .third_byte2:
  976.         mov     al, byte[esi]
  977.         neg     edx
  978.         add     edx, 8
  979.         mov     ecx, edx
  980.         mov     [bits_left], edx
  981.         shr     eax, cl
  982.   .code_done2:
  983.  
  984.  
  985.         mov     [old_code], eax
  986.         cmp     eax, 0x101      ; end of information
  987.         je      .quit
  988.  
  989.         push    esi
  990.         mov     esi, [table]
  991.         lea     esi, [esi + eax*8 + 256]
  992.         mov     ecx, dword[esi+4]
  993.  
  994.         mov     edx, [next_table_entry]
  995.         mov     [edx], edi
  996.         lea     eax, [ecx + 1]
  997.         mov     [edx + 4], eax
  998.         add     [next_table_entry], 8
  999.  
  1000.         mov     esi, [esi]
  1001.         rep     movsb
  1002.         pop     esi
  1003.         jmp     .begin
  1004.   .no_clear_code:
  1005.         cmp     eax, [table_size]
  1006.         ja      .not_in_table
  1007.         mov     [old_code], eax
  1008.         push    esi
  1009.         mov     esi, [table]
  1010.         lea     esi, [esi + eax*8 + 256]
  1011.         mov     ecx, dword[esi + 4]
  1012.  
  1013.         mov     edx, [next_table_entry]
  1014.         mov     [edx], edi
  1015.         lea     eax, [ecx + 1]
  1016.         mov     [edx + 4], eax
  1017.         add     [next_table_entry], 8
  1018.         add     [table_size], 1
  1019.  
  1020.         mov     esi, [esi]
  1021.         rep     movsb
  1022.         pop     esi
  1023.  
  1024.         dec     [shift_counter]
  1025.         jnz     @f
  1026.         mov     ecx, [cur_shift]
  1027.         add     [cur_shift], 1
  1028.         mov     edx, 1
  1029.         shl     edx, cl
  1030.         mov     [shift_counter], edx
  1031.     @@:
  1032.         jmp     .begin
  1033.  
  1034.   .not_in_table:
  1035.         xchg    eax, [old_code]
  1036.         push    esi
  1037.         mov     esi, [table]
  1038.         lea     esi, [esi + eax*8 + 256]
  1039.         mov     ecx, dword[esi+4]
  1040.  
  1041.         mov     edx, [next_table_entry]
  1042.         mov     [edx], edi
  1043.         lea     eax, [ecx + 2]
  1044.         mov     [edx + 4], eax
  1045.         add     [next_table_entry], 8
  1046.         add     [table_size], 1
  1047.  
  1048.         mov     esi, [esi]
  1049.         mov     al, [esi]
  1050.         rep     movsb
  1051.         mov     byte[edi], al
  1052.         add     edi, 1
  1053.         pop     esi
  1054.  
  1055.         dec     [shift_counter]
  1056.         jnz     @f
  1057.         mov     ecx, [cur_shift]
  1058.         add     [cur_shift], 1
  1059.         mov     edx, 1
  1060.         shl     edx, cl
  1061.         mov     [shift_counter], edx
  1062.     @@:
  1063.         jmp     .begin
  1064.  
  1065.   .quit:
  1066.         cmp     [table], 0
  1067.         je      @f
  1068.         invoke  mem.free, [table]
  1069.     @@:
  1070.         pop     esi edx ecx ebx
  1071.         ret
  1072. endp
  1073.  
  1074.  
  1075. proc    tiff._.write_run _width_left, _current_tree
  1076.  
  1077.         push    ebx
  1078.  
  1079.         test    eax, eax
  1080.         jz      .done
  1081.         sub     [_width_left], eax
  1082.         js      .error
  1083.         cmp     esi, tiff._.huffman_tree_black.begin
  1084.         seta    bh
  1085.  
  1086.         cmp     ecx, eax
  1087.         ja      .one_byte
  1088.   .many_bytes:
  1089.         mov     bl, [edi]
  1090.     @@:
  1091.         shl     bl, 1
  1092.         or      bl, bh
  1093.         dec     eax
  1094.         dec     ecx
  1095.         jnz     @b
  1096.         mov     [edi], bl
  1097.         inc     edi
  1098.         mov     ecx, eax
  1099.         and     eax, 0x07
  1100.         shr     ecx, 3
  1101.  
  1102.         push    eax
  1103.         xor     eax, eax
  1104.         test    bh, bh
  1105.         jz      @f
  1106.         dec     al
  1107.     @@:
  1108.         rep     stosb
  1109.         pop     eax
  1110.  
  1111.         mov     ecx, 8
  1112.         test    eax, eax
  1113.         jz      .done
  1114.  
  1115.   .one_byte:
  1116.         mov     bl, [edi]
  1117.     @@:
  1118.         shl     bl, 1
  1119.         or      bl, bh
  1120.         dec     ecx
  1121.         dec     eax
  1122.         jnz     @b
  1123.         mov     byte[edi], bl
  1124.  
  1125.         cmp     [_width_left], 0
  1126.         jne     .done
  1127.         mov     bl, [edi]
  1128.         shl     bl, cl
  1129.         mov     byte[edi], bl
  1130.         inc     edi
  1131.   .done:
  1132.         mov     eax, [_width_left]
  1133.         jmp     .quit
  1134.   .error:
  1135.   .quit:
  1136.         pop     ebx
  1137.         ret
  1138. endp
  1139.  
  1140.  
  1141. proc    tiff._.get_word _endianness
  1142.  
  1143.         lodsw
  1144.         test    [_endianness], 1
  1145.         jnz     @f
  1146.         ret
  1147.     @@:
  1148.         xchg    al, ah
  1149.         ret
  1150. endp
  1151.  
  1152.  
  1153. proc    tiff._.get_dword _endianness
  1154.  
  1155.         lodsd
  1156.         test    [_endianness], 1
  1157.         jnz     @f
  1158.         ret
  1159.     @@:
  1160.         bswap   eax
  1161.         ret
  1162.  
  1163.         ret
  1164. endp
  1165.  
  1166.  
  1167. proc    tiff._.pack_8a _img
  1168.         mov     ebx, [_img]
  1169.         mov     esi, [ebx + Image.Data]
  1170.         mov     edi, esi
  1171.         mov     ecx, [ebx + Image.Width]
  1172.         imul    ecx, [ebx + Image.Height]
  1173.     @@:
  1174.         lodsw
  1175.         stosb
  1176.         dec     ecx
  1177.         jnz     @b
  1178.         ret
  1179. endp
  1180.  
  1181.  
  1182. proc tiff._.planar_to_separate _img
  1183. locals
  1184.         pixels          rd 1
  1185.         tmp_image       rd 1
  1186.         channels        rd 1
  1187.         channel_padding rd 1
  1188. endl
  1189.         pushad
  1190.         mov     ebx, [_img]
  1191.         mov     ecx, [ebx + Image.Width]
  1192.         imul    ecx, [ebx + Image.Height]
  1193.         mov     [pixels], ecx
  1194.         cmp     [ebx + Image.Type], Image.bpp24
  1195.         je      .bpp24
  1196.         cmp     [ebx + Image.Type], Image.bpp32
  1197.         je      .bpp32
  1198. ;        cmp     [ebx + Image.Type], Image.bpp4
  1199. ;        je      .bpp4
  1200.         jmp     .quit
  1201.   .bpp24:
  1202.         mov     [channels], 3
  1203.         mov     [channel_padding], 2
  1204.         lea     eax, [ecx*3]
  1205.         jmp     .proceed
  1206.   .bpp32:
  1207.         mov     [channels], 4
  1208.         mov     [channel_padding], 3
  1209.         shl     eax, 2
  1210.         jmp     .proceed
  1211.   .bpp4:
  1212.         mov     [channels], 3
  1213.         mov     [channel_padding], 2
  1214.         shr     eax, 1
  1215.         jmp     .proceed
  1216.   .proceed:
  1217.         invoke  mem.alloc, eax
  1218.         test    eax, eax
  1219.         jz      .quit
  1220.         mov     [tmp_image], eax
  1221.   .channel:
  1222.         mov     esi, [ebx + Image.Data]
  1223.         mov     edi, [tmp_image]
  1224.         mov     ecx, [pixels]
  1225.         mov     eax, [channel_padding]
  1226.         inc     eax
  1227.         sub     eax, [channels]
  1228.         add     edi, eax
  1229.         mov     eax, [channels]
  1230.         dec     eax
  1231.         imul    eax, [pixels]
  1232.         add     esi, eax
  1233.     @@:
  1234.         lodsb
  1235.         stosb
  1236.         add     edi, [channel_padding]
  1237.         dec     ecx
  1238.         jnz     @b
  1239.         dec     [channels]
  1240.         jnz     .channel
  1241.  
  1242.   .quit:
  1243.         mov     eax, [tmp_image]
  1244.         xchg    [ebx + Image.Data], eax
  1245.         invoke  mem.free, eax
  1246.         popad
  1247.         ret
  1248. endp
  1249.  
  1250.  
  1251. proc tiff._.get_palette _num_colors, _endianness
  1252.         mov     esi, [ebx + tiff_extra.palette]
  1253.         push    ebx
  1254.         mov     ebx, 2
  1255.   .bpp2.channel:
  1256.         mov     edi, ebx
  1257.         add     edi, [edx + Image.Palette]
  1258.         mov     ecx, [_num_colors]
  1259.     @@:
  1260.         lodsw_
  1261.         shr     eax, 8
  1262.         stosb
  1263.         add     edi, 3
  1264.         dec     ecx
  1265.         jnz     @b
  1266.         dec     ebx
  1267.         jns     .bpp2.channel
  1268.         pop     ebx
  1269.         ret
  1270. endp
  1271.  
  1272. ;;================================================================================================;;
  1273. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1274. ;;================================================================================================;;
  1275. ;! Below is private data you should never use directly from your code                             ;;
  1276. ;;================================================================================================;;
  1277. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1278. ;;================================================================================================;;
  1279. tiff.IFDE_tag_table.begin:
  1280.   .tag_100:             dd      0x0100, tiff._.parse_IFDE.tag_100               ; image width
  1281.   .tag_101:             dd      0x0101, tiff._.parse_IFDE.tag_101               ; image height (this is called 'length' in spec)
  1282.   .tag_102:             dd      0x0102, tiff._.parse_IFDE.tag_102               ; bits per sample
  1283.   .tag_103:             dd      0x0103, tiff._.parse_IFDE.tag_103               ; compression
  1284.   .tag_106:             dd      0x0106, tiff._.parse_IFDE.tag_106               ; photometric interpretation
  1285.   .tag_111:             dd      0x0111, tiff._.parse_IFDE.tag_111               ; strip offsets
  1286.   .tag_115:             dd      0x0115, tiff._.parse_IFDE.tag_115               ; samples per pixel
  1287.   .tag_116:             dd      0x0116, tiff._.parse_IFDE.tag_116               ; rows per strip
  1288.   .tag_117:             dd      0x0117, tiff._.parse_IFDE.tag_117               ; strip byte counts
  1289.   .tag_11c:             dd      0x011c, tiff._.parse_IFDE.tag_11c               ; planar configuration
  1290.   .tag_13d:             dd      0x013d, tiff._.parse_IFDE.tag_13d               ; predictor
  1291.   .tag_140:             dd      0x0140, tiff._.parse_IFDE.tag_140               ; color map
  1292.   .tag_152:             dd      0x0152, tiff._.parse_IFDE.tag_152               ; extra samples
  1293. tiff.IFDE_tag_table.end:
  1294.  
  1295. include 'huffman.asm'           ; huffman trees for ccitt1d compression method
  1296.