Subversion Repositories Kolibri OS

Rev

Rev 2733 | Rev 3053 | 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.         push    ebx
  399.         mov     edi, [ebx + tiff_extra.samples_per_pixel]
  400.         mov     edx, edi
  401.         mov     ebx, [retvalue]
  402.   .post.predictor.plane:
  403.         mov     esi, [ebx + Image.Data]
  404.         sub     esi, 1
  405.         add     esi, edx
  406.         mov     ecx, [ebx + Image.Height]
  407.   .post.predictor.line:
  408.         push    ecx
  409.         mov     ecx, [ebx + Image.Width]
  410.         sub     ecx, 1
  411.         mov     ah, byte[esi]
  412.         add     esi, edi
  413.     @@:
  414.         mov     al, byte[esi]
  415.         add     al, ah
  416.         mov     byte[esi], al
  417.         add     esi, edi
  418.         shl     eax, 8
  419.         dec     ecx
  420.         jnz     @b
  421.         pop     ecx
  422.         dec     ecx
  423.         jnz     .post.predictor.line
  424.         dec     edx
  425.         jnz     .post.predictor.plane
  426.         pop     ebx
  427.  
  428.   .post.end:
  429.  
  430.   .pop_quit:
  431.         pop     esi
  432.   .quit:
  433.         pop     edi edx ebx
  434.         mov     eax, [retvalue]
  435.         ret
  436. endp
  437.  
  438. proc tiff._.parse_IFDE _data, _endianness
  439.  
  440.         push    ebx edx edi
  441.  
  442.         lodsw_
  443.         mov     edx, tiff.IFDE_tag_table.begin
  444.         mov     ecx, (tiff.IFDE_tag_table.end-tiff.IFDE_tag_table.begin)/8
  445.   .tag:
  446.         cmp     ax, word[edx]
  447.         jne     @f
  448.         lodsw_
  449.         jmp     dword[edx + 4]
  450.     @@:
  451.         add     edx, 8
  452.         dec     ecx
  453.         jnz     .tag
  454.   .tag_default:                                         ; unknown/unsupported/unimportant
  455.         lodsw
  456.         lodsd
  457.         lodsd
  458.         jmp     .quit                                   ; just skip it
  459.  
  460.   .tag_100:                                             ; ImageWidth
  461.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  462.         jne     @f
  463.         lodsd
  464.         xor     eax, eax
  465.         lodsw_
  466.         mov     [ebx + tiff_extra.image_width], eax
  467.         lodsw
  468.         jmp     .quit
  469.     @@:
  470.         cmp     ax, TIFF.IFDE_TYPE.LONG
  471.         jne     @f
  472.         lodsd
  473.         lodsd_
  474.         mov     [ebx + tiff_extra.image_width], eax
  475.         jmp     .quit
  476.     @@:
  477.         jmp     .quit
  478.  
  479.   .tag_101:                                             ; ImageHeight
  480.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  481.         jne     @f
  482.         lodsd
  483.         xor     eax, eax
  484.         lodsw_
  485.         mov     [ebx + tiff_extra.image_height], eax
  486.         lodsw
  487.         jmp     .quit
  488.     @@:
  489.         cmp     ax, TIFF.IFDE_TYPE.LONG
  490.         jne     @f
  491.         lodsd
  492.         lodsd_
  493.         mov     [ebx + tiff_extra.image_height], eax
  494.         jmp     .quit
  495.     @@:
  496.         jmp     .quit
  497.  
  498.   .tag_102:                                             ; BitsPerSample
  499.         lodsd_
  500.         imul    eax, TIFF.IFDE_TYPE_LENGTH.SHORT
  501.         cmp     eax, 4
  502.         ja      @f
  503.         xor     eax, eax
  504.         lodsw_
  505.         mov     [ebx + tiff_extra.bits_per_sample], eax
  506.         lodsw
  507.         jmp     .quit
  508.     @@:
  509.         lodsd_
  510.         add     eax, [_data]
  511.         push    esi
  512.         mov     esi, eax
  513.         xor     eax, eax
  514.         lodsw_
  515.         pop     esi
  516.         mov     [ebx + tiff_extra.bits_per_sample], eax
  517.         jmp     .quit
  518.  
  519.   .tag_103:                                             ; Compression
  520.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  521.         jne     @f
  522.         lodsd
  523.         xor     eax, eax
  524.         lodsw_
  525.         mov     [ebx + tiff_extra.compression], eax
  526.         lodsw
  527.         jmp     .quit
  528.     @@:
  529.         jmp     .quit
  530.  
  531.   .tag_106:                                             ; PhotometricInterpretation
  532.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  533.         jne     @f
  534.         lodsd
  535.         xor     eax, eax
  536.         lodsw_
  537.         mov     [ebx + tiff_extra.photometric], eax
  538.         lodsw
  539.         jmp     .quit
  540.     @@:
  541.  
  542.         jmp     .quit
  543.  
  544.   .tag_111:                                             ; StripOffsets
  545.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  546.         jne     @f
  547.         mov     [ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  548.         jmp     .tag_111.common
  549.     @@:
  550.         mov     [ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.LONG
  551.   .tag_111.common:
  552.         lodsd_
  553.         mov     [ebx + tiff_extra.offsets_number], eax
  554.         imul    eax, [ebx+tiff_extra.strip_offsets_length]
  555.         cmp     eax, 4
  556.         ja      @f
  557.         mov     [ebx + tiff_extra.strip_offsets], esi
  558.         lodsd
  559.         jmp     .quit
  560.     @@:
  561.         lodsd_
  562.         add     eax, [_data]
  563.         mov     [ebx + tiff_extra.strip_offsets], eax
  564.         jmp     .quit
  565.  
  566.   .tag_115:                                             ; SamplesPerPixel
  567.         lodsd_
  568.         imul    eax, TIFF.IFDE_TYPE_LENGTH.SHORT
  569.         cmp     eax, 4
  570.         ja      @f
  571.         xor     eax, eax
  572.         lodsw_
  573.         mov     [ebx + tiff_extra.samples_per_pixel], eax
  574.         lodsw
  575.         jmp     .quit
  576.     @@:
  577.         lodsd_
  578.         add     eax, [_data]
  579.         movzx   eax, word[eax]
  580.         jmp     .quit
  581.  
  582.   .tag_116:                                             ; RowsPerStrip
  583.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  584.         jne     @f
  585.         lodsd
  586.         xor     eax, eax
  587.         lodsw_
  588.         mov     [ebx + tiff_extra.rows_per_strip], eax
  589.         lodsw
  590.         jmp     .quit
  591.     @@:
  592.         lodsd
  593.         lodsd_
  594.         mov     [ebx + tiff_extra.rows_per_strip], eax
  595.         jmp     .quit
  596.  
  597.   .tag_117:                                             ; StripByteCounts
  598.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  599.         jne     @f
  600.         mov     [ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  601.         jmp     .tag_117.common
  602.     @@:
  603.         mov     [ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.LONG
  604.   .tag_117.common:
  605.         lodsd_
  606.         imul    eax, [ebx + tiff_extra.strip_byte_counts_length]
  607.         cmp     eax, 4
  608.         ja      @f
  609.         mov     [ebx + tiff_extra.strip_byte_counts], esi
  610.         lodsd
  611.         jmp     .quit
  612.     @@:
  613.         lodsd_
  614.         add     eax, [_data]
  615.         mov     [ebx + tiff_extra.strip_byte_counts], eax
  616.         jmp     .quit
  617.  
  618.   .tag_13d:                                             ; Predictor
  619.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  620.         jne     @f
  621.         lodsd
  622.         xor     eax, eax
  623.         lodsw_
  624.         mov     [ebx + tiff_extra.predictor], eax
  625.         lodsw
  626.     @@:
  627.         jmp     .quit
  628.  
  629.   .tag_140:                                             ; ColorMap
  630.         lodsd
  631.         lodsd_
  632.         add     eax, [_data]
  633.         mov     [ebx + tiff_extra.palette], eax
  634.         jmp     .quit
  635.   .tag_152:                                             ; ExtraSamples
  636.         mov     [ebx + tiff_extra.extra_samples], esi
  637.         mov     ecx, [ebx + tiff_extra.extra_samples_number]
  638.         rep     lodsw   ; ignored
  639.         jmp     .quit
  640.  
  641.   .quit:
  642.         pop     edi edx ebx
  643.         ret
  644. endp
  645.  
  646.  
  647. proc tiff._.define_image_type
  648.  
  649.         xor     eax, eax
  650.  
  651.         cmp     [ebx + tiff_extra.photometric], TIFF.PHOTOMETRIC.RGB
  652.         jne     .not_full_color
  653.         mov     eax, -3
  654.         add     eax, [ebx + tiff_extra.samples_per_pixel]
  655.         mov     [ebx + tiff_extra.extra_samples_number], eax
  656.         dec     eax
  657.         jns     @f
  658.         mov     eax, Image.bpp24
  659.         jmp     .quit
  660.     @@:
  661.         dec     eax
  662.         jns     @f
  663.         mov     eax, Image.bpp32
  664. ;       mov     [ebx + tiff_extra.extra_samples_number], 0
  665.         jmp     .quit
  666.     @@:
  667.   .not_full_color:      ; grayscale, indexed, bilevel
  668.         cmp     [ebx + tiff_extra.bits_per_sample], 1
  669.         jg      .not_bilevel
  670.         mov     eax, Image.bpp1
  671.         jmp     .quit
  672.   .not_bilevel:         ; grayscale, indexed
  673.         cmp     [ebx + tiff_extra.palette], 0
  674.         je      .without_palette
  675.         cmp     [ebx + tiff_extra.bits_per_sample], 4
  676.         jne     @f
  677. ;       mov     eax, Image.bpp4
  678.         jmp     .quit
  679.     @@:
  680.         cmp     [ebx + tiff_extra.bits_per_sample], 8
  681.         jne     @f
  682.         mov     eax, Image.bpp8i
  683.         jmp     .quit
  684.     @@:
  685.         jmp     .quit
  686.   .without_palette:     ; grayscale
  687.         mov     eax, -1
  688.         add     eax, [ebx + tiff_extra.samples_per_pixel]
  689.         mov     [ebx + tiff_extra.extra_samples_number], eax
  690.         dec     eax
  691.         jns     @f
  692.         mov     eax, Image.bpp8g
  693.         jmp     .quit
  694.     @@:
  695.         mov     eax, Image.bpp8a
  696.         jmp     .quit
  697.   .quit:
  698.         ret
  699. endp
  700.  
  701.  
  702. proc tiff._.decompress.uncompressed _image
  703.  
  704.         rep     movsb
  705.         ret
  706. endp
  707.  
  708.  
  709. proc tiff._.decompress.packbits _image
  710.  
  711.         push    ebx ecx edx esi
  712.  
  713.         mov     edx, ecx
  714.  
  715.   .decode:
  716.         lodsb
  717.         dec     edx
  718.         cmp     al, 0x7f
  719.         jbe     .different
  720.         cmp     al, 0x80
  721.         jne     .identical
  722.         test    edx, edx
  723.         jz      .quit
  724.         jmp     .decode
  725.  
  726.   .identical:
  727.         neg     al
  728.         inc     al
  729.         movzx   ecx, al
  730.         dec     edx
  731.         lodsb
  732.         rep     stosb
  733.         test    edx, edx
  734.         jnz     .decode
  735.         jmp     .quit
  736.  
  737.   .different:
  738.         movzx   ecx, al
  739.         inc     ecx
  740.         sub     edx, ecx
  741.         rep     movsb
  742.         test    edx, edx
  743.         jnz     .decode
  744.  
  745.   .quit:
  746.         pop     esi edx ecx ebx
  747.         ret
  748. endp
  749.  
  750.  
  751. proc    tiff._.decompress.ccitt1d _image
  752. locals
  753.         current_tree            rd      1
  754.         old_tree                rd      1
  755.         width                   rd      1
  756.         height                  rd      1
  757.         width_left              rd      1
  758.         is_makeup               rd      1
  759. endl
  760.         push    ebx ecx edx esi
  761.         mov     [is_makeup], 0
  762.  
  763.         mov     ebx, [_image]
  764.         push    [ebx + Image.Height]
  765.         pop     [height]
  766.         push    [ebx + Image.Width]
  767.         pop     [width]
  768.  
  769.         mov     edx, esi
  770.   .next_scanline:
  771.         push    [width]
  772.         pop     [width_left]
  773.         dec     [height]
  774.         js      .error
  775.         mov     [current_tree], tiff._.huffman_tree_white.begin
  776.         mov     [old_tree], tiff._.huffman_tree_black.begin
  777.         mov     ebx, 0
  778.         mov     ecx, 8
  779.   .next_run:
  780.         mov     esi, [current_tree]
  781.   .branch:
  782.         lodsd
  783.         btr     eax, 31
  784.         jnc     .not_a_leaf
  785.         cmp     eax, 63
  786.         seta    byte[is_makeup]
  787.         ja      @f
  788.         push    [current_tree]
  789.         push    [old_tree]
  790.         pop     [current_tree]
  791.         pop     [old_tree]
  792.     @@:
  793.         stdcall tiff._.write_run, [width_left], [current_tree]
  794.         mov     [width_left], eax
  795.         test    byte[is_makeup], 0x01
  796.         jnz     .next_run
  797.         test    eax, eax
  798.         jnz     .next_run
  799.         jmp     .next_scanline
  800.   .not_a_leaf:
  801.         test    bh, bh
  802.         jnz     @f
  803.         mov     bl, byte[edx]
  804.         inc     edx
  805.         mov     bh, 8
  806.     @@:
  807.         test    al, 0x02
  808.         jz      .not_a_corner
  809.         dec     bh
  810.         sal     bl, 1
  811.         lahf
  812.         and     ah, 0x03
  813.         cmp     al, ah
  814.         jne     .error
  815.         mov     esi, [esi]
  816.         jmp     .branch
  817.   .not_a_corner:
  818.         lodsd
  819.         dec     bh
  820.         sal     bl, 1
  821.         jc      .branch
  822.         mov     esi, eax
  823.         jmp     .branch
  824.   .error:
  825.   .quit:
  826.         pop     esi edx ecx ebx
  827.         ret
  828. endp
  829.  
  830.  
  831. proc tiff._.decompress.lzw _image
  832. locals
  833.         cur_shift               rd 1    ; 9 -- 12
  834.         shift_counter           rd 1    ; how many shifts of current length remained
  835.         bits_left               rd 1    ; in current byte ( pointed to by [esi] )
  836.         table                   rd 1
  837.         table_size              rd 1    ; the number of entries
  838.         old_code                rd 1
  839.         next_table_entry        rd 1    ; where to place new entry
  840. endl
  841.         push    ebx ecx edx esi
  842.  
  843.         mov     [table], 0
  844.         mov     [bits_left], 8
  845.         mov     [cur_shift], 9
  846.  
  847.   .begin:
  848.  
  849.  ; .getnextcode:
  850.         xor     eax, eax
  851.         mov     edx, [cur_shift]
  852.  
  853.         lodsb
  854.         mov     ecx, [bits_left]
  855.         mov     ch, cl
  856.         neg     cl
  857.         add     cl, 8
  858.         shl     al, cl
  859.         mov     cl, ch
  860.         shl     eax, cl
  861.         sub     edx, [bits_left]
  862.         ; second_byte
  863.         cmp     edx, 8
  864.         je      .enough_zero
  865.         jb      .enough_nonzero
  866.         sub     edx, 8
  867.         lodsb
  868.         shl     eax, 8
  869.         jmp     .third_byte
  870.   .enough_zero:
  871.         mov     [bits_left], 8
  872.         lodsb
  873.         jmp     .code_done
  874.   .enough_nonzero:
  875.         mov     al, byte[esi]
  876.         neg     edx
  877.         add     edx, 8
  878.         mov     ecx, edx
  879.         mov     [bits_left], edx
  880.         shr     eax, cl
  881.         jmp     .code_done
  882.   .third_byte:
  883.         mov     al, byte[esi]
  884.         neg     edx
  885.         add     edx, 8
  886.         mov     ecx, edx
  887.         mov     [bits_left], edx
  888.         shr     eax, cl
  889.   .code_done:
  890.  
  891.  
  892.         mov     ebx, eax
  893.         cmp     ebx, 0x101      ; end of information
  894.         je      .quit
  895.         cmp     ebx, 0x100      ; clear code
  896.         jne     .no_clear_code
  897.  
  898.         cmp     [table], 0
  899.         jne     @f
  900.         invoke  mem.alloc, 256 + 63488  ; 256 + (2^8 + 2^9 + 2^10 + 2^11 + 2^12)*(4+4)
  901.         test    eax, eax
  902.         jz      .quit
  903.         mov     [table], eax
  904.     @@:
  905.         mov     eax, [table]
  906.         mov     [next_table_entry], eax
  907.         add     [next_table_entry], 256 + (256*8) + 2*8
  908.         mov     [cur_shift], 9
  909.         mov     [shift_counter], 256-3  ; clear code, end of information, why -3?
  910.         mov     [table_size], 257
  911.  
  912.         push    edi
  913.         mov     ecx, 256
  914.         mov     edi, [table]
  915.         mov     ebx, edi
  916.         add     edi, 256
  917.         mov     eax, 0
  918.     @@:
  919.         mov     byte[ebx], al
  920.         mov     [edi], ebx
  921.         add     edi, 4
  922.         add     ebx, 1
  923.         add     eax, 1
  924.         mov     [edi], dword 1
  925.         add     edi, 4
  926.         dec     ecx
  927.         jnz     @b
  928.         pop     edi
  929. ;  .getnextcode:
  930.         xor     eax, eax
  931.         mov     edx, [cur_shift]
  932.  
  933.         lodsb
  934.         mov     ecx, [bits_left]
  935.         mov     ch, cl
  936.         neg     cl
  937.         add     cl, 8
  938.         shl     al, cl
  939.         mov     cl, ch
  940.         shl     eax, cl
  941.         sub     edx, [bits_left]
  942.         ; second_byte
  943.         cmp     edx, 8
  944.         je      .enough_zero2
  945.         jb      .enough_nonzero2
  946.         sub     edx, 8
  947.         lodsb
  948.         shl     eax, 8
  949.         jmp     .third_byte2
  950.   .enough_zero2:
  951.         mov     [bits_left], 8
  952.         lodsb
  953.         jmp     .code_done2
  954.   .enough_nonzero2:
  955.         mov     al, byte[esi]
  956.         neg     edx
  957.         add     edx, 8
  958.         mov     ecx, edx
  959.         mov     [bits_left], edx
  960.         shr     eax, cl
  961.         jmp     .code_done2
  962.   .third_byte2:
  963.         mov     al, byte[esi]
  964.         neg     edx
  965.         add     edx, 8
  966.         mov     ecx, edx
  967.         mov     [bits_left], edx
  968.         shr     eax, cl
  969.   .code_done2:
  970.  
  971.  
  972.         mov     [old_code], eax
  973.         cmp     eax, 0x101      ; end of information
  974.         je      .quit
  975.  
  976.         push    esi
  977.         mov     esi, [table]
  978.         lea     esi, [esi + eax*8 + 256]
  979.         mov     ecx, dword[esi+4]
  980.  
  981.         mov     edx, [next_table_entry]
  982.         mov     [edx], edi
  983.         lea     eax, [ecx + 1]
  984.         mov     [edx + 4], eax
  985.         add     [next_table_entry], 8
  986.  
  987.         mov     esi, [esi]
  988.         rep     movsb
  989.         pop     esi
  990.         jmp     .begin
  991.   .no_clear_code:
  992.         cmp     eax, [table_size]
  993.         ja      .not_in_table
  994.         mov     [old_code], eax
  995.         push    esi
  996.         mov     esi, [table]
  997.         lea     esi, [esi + eax*8 + 256]
  998.         mov     ecx, dword[esi + 4]
  999.  
  1000.         mov     edx, [next_table_entry]
  1001.         mov     [edx], edi
  1002.         lea     eax, [ecx + 1]
  1003.         mov     [edx + 4], eax
  1004.         add     [next_table_entry], 8
  1005.         add     [table_size], 1
  1006.  
  1007.         mov     esi, [esi]
  1008.         rep     movsb
  1009.         pop     esi
  1010.  
  1011.         dec     [shift_counter]
  1012.         jnz     @f
  1013.         mov     ecx, [cur_shift]
  1014.         add     [cur_shift], 1
  1015.         mov     edx, 1
  1016.         shl     edx, cl
  1017.         mov     [shift_counter], edx
  1018.     @@:
  1019.         jmp     .begin
  1020.  
  1021.   .not_in_table:
  1022.         xchg    eax, [old_code]
  1023.         push    esi
  1024.         mov     esi, [table]
  1025.         lea     esi, [esi + eax*8 + 256]
  1026.         mov     ecx, dword[esi+4]
  1027.  
  1028.         mov     edx, [next_table_entry]
  1029.         mov     [edx], edi
  1030.         lea     eax, [ecx + 2]
  1031.         mov     [edx + 4], eax
  1032.         add     [next_table_entry], 8
  1033.         add     [table_size], 1
  1034.  
  1035.         mov     esi, [esi]
  1036.         mov     al, [esi]
  1037.         rep     movsb
  1038.         mov     byte[edi], al
  1039.         add     edi, 1
  1040.         pop     esi
  1041.  
  1042.         dec     [shift_counter]
  1043.         jnz     @f
  1044.         mov     ecx, [cur_shift]
  1045.         add     [cur_shift], 1
  1046.         mov     edx, 1
  1047.         shl     edx, cl
  1048.         mov     [shift_counter], edx
  1049.     @@:
  1050.         jmp     .begin
  1051.  
  1052.   .quit:
  1053.         cmp     [table], 0
  1054.         je      @f
  1055.         invoke  mem.free, [table]
  1056.     @@:
  1057.         pop     esi edx ecx ebx
  1058.         ret
  1059. endp
  1060.  
  1061.  
  1062. proc    tiff._.write_run _width_left, _current_tree
  1063.  
  1064.         push    ebx
  1065.  
  1066.         test    eax, eax
  1067.         jz      .done
  1068.         sub     [_width_left], eax
  1069.         js      .error
  1070.         cmp     esi, tiff._.huffman_tree_black.begin
  1071.         seta    bh
  1072.  
  1073.         cmp     ecx, eax
  1074.         ja      .one_byte
  1075.   .many_bytes:
  1076.         mov     bl, [edi]
  1077.     @@:
  1078.         shl     bl, 1
  1079.         or      bl, bh
  1080.         dec     eax
  1081.         dec     ecx
  1082.         jnz     @b
  1083.         mov     [edi], bl
  1084.         inc     edi
  1085.         mov     ecx, eax
  1086.         and     eax, 0x07
  1087.         shr     ecx, 3
  1088.  
  1089.         push    eax
  1090.         xor     eax, eax
  1091.         test    bh, bh
  1092.         jz      @f
  1093.         dec     al
  1094.     @@:
  1095.         rep     stosb
  1096.         pop     eax
  1097.  
  1098.         mov     ecx, 8
  1099.         test    eax, eax
  1100.         jz      .done
  1101.  
  1102.   .one_byte:
  1103.         mov     bl, [edi]
  1104.     @@:
  1105.         shl     bl, 1
  1106.         or      bl, bh
  1107.         dec     ecx
  1108.         dec     eax
  1109.         jnz     @b
  1110.         mov     byte[edi], bl
  1111.  
  1112.         cmp     [_width_left], 0
  1113.         jne     .done
  1114.         mov     bl, [edi]
  1115.         shl     bl, cl
  1116.         mov     byte[edi], bl
  1117.         inc     edi
  1118.   .done:
  1119.         mov     eax, [_width_left]
  1120.         jmp     .quit
  1121.   .error:
  1122.   .quit:
  1123.         pop     ebx
  1124.         ret
  1125. endp
  1126.  
  1127.  
  1128. proc    tiff._.get_word _endianness
  1129.  
  1130.         lodsw
  1131.         test    [_endianness], 1
  1132.         jnz     @f
  1133.         ret
  1134.     @@:
  1135.         xchg    al, ah
  1136.         ret
  1137. endp
  1138.  
  1139.  
  1140. proc    tiff._.get_dword _endianness
  1141.  
  1142.         lodsd
  1143.         test    [_endianness], 1
  1144.         jnz     @f
  1145.         ret
  1146.     @@:
  1147.         bswap   eax
  1148.         ret
  1149.  
  1150.         ret
  1151. endp
  1152.  
  1153.  
  1154. proc    tiff._.pack_8a _img
  1155.         mov     ebx, [_img]
  1156.         mov     esi, [ebx + Image.Data]
  1157.         mov     edi, esi
  1158.         mov     ecx, [ebx + Image.Width]
  1159.         imul    ecx, [ebx + Image.Height]
  1160.     @@:
  1161.         lodsw
  1162.         stosb
  1163.         dec     ecx
  1164.         jnz     @b
  1165.         ret
  1166. endp
  1167.  
  1168. ;;================================================================================================;;
  1169. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1170. ;;================================================================================================;;
  1171. ;! Below is private data you should never use directly from your code                             ;;
  1172. ;;================================================================================================;;
  1173. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1174. ;;================================================================================================;;
  1175. tiff.IFDE_tag_table.begin:
  1176.   .tag_100:             dd      0x0100, tiff._.parse_IFDE.tag_100               ; image width
  1177.   .tag_101:             dd      0x0101, tiff._.parse_IFDE.tag_101               ; image height (this is called 'length' in spec)
  1178.   .tag_102:             dd      0x0102, tiff._.parse_IFDE.tag_102               ; bits per sample
  1179.   .tag_103:             dd      0x0103, tiff._.parse_IFDE.tag_103               ; compression
  1180.   .tag_106:             dd      0x0106, tiff._.parse_IFDE.tag_106               ; photometric interpretation
  1181.   .tag_111:             dd      0x0111, tiff._.parse_IFDE.tag_111               ; strip offsets
  1182.   .tag_115:             dd      0x0115, tiff._.parse_IFDE.tag_115               ; samples per pixel
  1183.   .tag_116:             dd      0x0116, tiff._.parse_IFDE.tag_116               ; rows per strip
  1184.   .tag_117:             dd      0x0117, tiff._.parse_IFDE.tag_117               ; strip byte counts
  1185.   .tag_13d:             dd      0x013d, tiff._.parse_IFDE.tag_13d               ; predictor
  1186.   .tag_140:             dd      0x0140, tiff._.parse_IFDE.tag_140               ; color map
  1187.   .tag_152:             dd      0x0152, tiff._.parse_IFDE.tag_152               ; extra samples
  1188. tiff.IFDE_tag_table.end:
  1189.  
  1190. include 'huffman.asm'           ; huffman trees for ccitt1d compression method
  1191.