Subversion Repositories Kolibri OS

Rev

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

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