Subversion Repositories Kolibri OS

Rev

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