Subversion Repositories Kolibri OS

Rev

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