Subversion Repositories Kolibri OS

Rev

Rev 2397 | Rev 2992 | 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.         mov     [decompress], tiff._.decompress.ccitt1d
  179.         jmp     .decompressor_defined
  180.         jmp     .quit
  181.   .decompressor_defined:
  182.  
  183.         push    esi             ; fixme!!
  184.  
  185.         mov     ecx, [edx + Image.Type]
  186.         dec     ecx
  187.         jz      .bpp8i
  188.         dec     ecx
  189.         jz      .bpp24
  190.         dec     ecx
  191.         jz      .bpp32
  192.         dec     ecx
  193.         dec     ecx             ; tiff doesn't handle 15bpp images
  194.         jz      .bpp16
  195.         dec     ecx
  196.         jz      .bpp1
  197.         dec     ecx
  198.         jz      .bpp8g
  199.         dec     ecx
  200.         jz      .bpp8a
  201. ;error report!!
  202.  
  203.   .bpp1:
  204.   .bpp1.palette:
  205.         mov     edi, [edx+Image.Palette]
  206.         cmp     [ebx + tiff_extra.photometric], TIFF.PHOTOMETRIC.BLACK_IS_ZERO
  207.         jne     .bpp1.white_is_zero
  208.   .bpp1.black_is_zero:
  209.         mov     [edi], dword 0x00000000
  210.         mov     [edi + 4], dword 0x00ffffff
  211.         jmp     .common
  212.   .bpp1.white_is_zero:
  213.         mov     [edi], dword 0x00ffffff
  214.         mov     [edi + 4], dword 0x00000000
  215.         jmp     .common
  216.  
  217.   .bpp4:
  218.         jmp     .common
  219.  
  220.   .bpp8i:
  221.         mov     esi, [ebx + tiff_extra.palette]
  222.         mov     ah, 2
  223.   .bpp8.channel:
  224.         mov     edi, eax
  225.         and     edi, 0x0000ff00
  226.         shr     edi, 8
  227.         add     edi, [edx + Image.Palette]
  228.         mov     ecx, 256
  229.     @@:
  230.         lodsb
  231.         stosb
  232.         lodsb
  233.         add     edi, 3
  234.         dec     ecx
  235.         jnz     @b
  236.         dec     ah
  237.         jns     .bpp8.channel
  238.         jmp     .common
  239.   .bpp8g:
  240.         jmp     .common
  241.  
  242.   .bpp8a:
  243.         jmp     .common
  244.  
  245.   .bpp16:
  246.         jmp     .common
  247.  
  248.   .bpp24:
  249.         jmp     .common
  250.  
  251.   .bpp32:
  252.         jmp     .common
  253.  
  254.  
  255.   .common:
  256.         mov     edi, [edx+Image.Data]
  257.         mov     esi, [ebx+tiff_extra.strip_offsets]
  258.         mov     edx, [ebx+tiff_extra.strip_byte_counts]
  259.  
  260.  
  261.         cmp     [ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  262.         jne     .l_x
  263.         cmp     [ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  264.         jne     .s_l
  265.         jmp     .s_s
  266.   .l_x: cmp     [ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  267.         jne     .l_l
  268.         jmp     .l_s
  269.  
  270.   .s_s:
  271.         xor     eax, eax
  272.         lodsw_
  273.         push    esi
  274.         mov     esi, eax
  275.         add     esi, [_data]
  276.         xor     ecx, ecx
  277.         mov     cx, word[edx]
  278.         test    [_endianness], 1
  279.         jz      @f
  280.         xchg    cl, ch
  281.     @@:
  282.         add     edx, 2
  283.         stdcall [decompress], [retvalue]
  284.         pop     esi
  285.         dec     [ebx + tiff_extra.offsets_number]
  286.         jnz     .s_s
  287.         jmp     .decoded
  288.  
  289.   .s_l:
  290.         xor     eax, eax
  291.         lodsw_
  292.         push    esi
  293.         mov     esi, eax
  294.         add     esi, [_data]
  295.         mov     ecx, [edx]
  296.         test    [_endianness], 1
  297.         jz      @f
  298.         bswap   ecx
  299.     @@:
  300.         add     edx, 4
  301.         stdcall [decompress], [retvalue]
  302.         pop     esi
  303.         dec     [ebx + tiff_extra.offsets_number]
  304.         jnz     .s_l
  305.         jmp     .decoded
  306.  
  307.   .l_s:
  308.         lodsd_
  309.         push    esi
  310.         mov     esi, eax
  311.         add     esi, [_data]
  312.         xor     ecx, ecx
  313.         mov     cx, word[edx]
  314.         test    [_endianness], 1
  315.         jz      @f
  316.         xchg    cl, ch
  317.     @@:
  318.         add     edx, 2
  319.         stdcall [decompress], [retvalue]
  320.         pop     esi
  321.         dec     [ebx + tiff_extra.offsets_number]
  322.         jnz     .l_s
  323.         jmp     .decoded
  324.  
  325.   .l_l:
  326.         lodsd_
  327.         push    esi
  328.         mov     esi, eax
  329.         add     esi, [_data]
  330.         mov     ecx, [edx]
  331.         test    [_endianness], 1
  332.         jz      @f
  333.         bswap   ecx
  334.     @@:
  335.         add     edx, 4
  336.         stdcall [decompress], [retvalue]
  337.         pop     esi
  338.         dec     [ebx + tiff_extra.offsets_number]
  339.         jnz     .l_l
  340.         jmp     .decoded
  341.  
  342.  
  343.   .decoded:
  344.   .check1:
  345.         cmp     [ebx + tiff_extra.samples_per_pixel], 3
  346.         jne     .check2
  347.         mov     eax, [retvalue]
  348.         mov     esi, [eax + Image.Data]
  349.         mov     edi, [eax + Image.Data]
  350.         mov     ecx, [eax + Image.Width]
  351.         imul    ecx, [eax + Image.Height]
  352.     @@:
  353.         lodsw
  354.         movsb
  355.         mov     byte[esi - 1], al
  356.         add     edi, 2
  357.         dec     ecx
  358.         jnz     @b
  359.         jmp     .pop_quit
  360.   .check2:
  361.         mov     ebx, [retvalue]
  362.         cmp     [ebx + Image.Type], Image.bpp8a
  363.         jne     .pop_quit
  364.         stdcall tiff._.pack_8a, ebx
  365.         mov     [ebx + Image.Type], Image.bpp8g
  366. ;       mov     eax, [ebx + Image.Width]
  367. ;       imul    eax, [ebx + Image.Height]
  368. ;       mov     ecx, eax
  369. ;       add     ecx, [ebx + Image.Data]
  370. ;       mov     [ebx + Image.Palette], ecx
  371. ;       add     eax, 256*4
  372. ;       stdcall [mem.realloc], [ebx + Image.Data], eax
  373. ;       mov     edi, [ebx + Image.Palette]
  374. ;       mov     eax, 0xff000000
  375. ;    @@:
  376. ;       stosd
  377. ;       add     eax, 0x00010101
  378. ;       jnc     @b
  379.  
  380.   .pop_quit:
  381.         pop     esi
  382.   .quit:
  383.         pop     edi edx ebx
  384.         mov     eax, [retvalue]
  385.         ret
  386. endp
  387.  
  388. proc tiff._.parse_IFDE _data, _endianness
  389.  
  390.         push    ebx edx edi
  391.  
  392.         lodsw_
  393.         mov     edx, tiff.IFDE_tag_table.begin
  394.         mov     ecx, (tiff.IFDE_tag_table.end-tiff.IFDE_tag_table.begin)/8
  395.   .tag:
  396.         cmp     ax, word[edx]
  397.         jne     @f
  398.         lodsw_
  399.         jmp     dword[edx + 4]
  400.     @@:
  401.         add     edx, 8
  402.         dec     ecx
  403.         jnz     .tag
  404.   .tag_default:                                         ; unknown/unsupported/uninteresting/unimportant
  405.         lodsw
  406.         lodsd
  407.         lodsd
  408.         jmp     .quit                                   ; just skip it
  409.  
  410.   .tag_100:                                             ; ImageWidth
  411.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  412.         jne     @f
  413.         lodsd
  414.         xor     eax, eax
  415.         lodsw_
  416.         mov     [ebx + tiff_extra.image_width], eax
  417.         lodsw
  418.         jmp     .quit
  419.     @@:
  420.         cmp     ax, TIFF.IFDE_TYPE.LONG
  421.         jne     @f
  422.         lodsd
  423.         lodsd_
  424.         mov     [ebx + tiff_extra.image_width], eax
  425.         jmp     .quit
  426.     @@:
  427.         jmp     .quit
  428.  
  429.   .tag_101:                                             ; ImageHeight
  430.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  431.         jne     @f
  432.         lodsd
  433.         xor     eax, eax
  434.         lodsw_
  435.         mov     [ebx + tiff_extra.image_height], eax
  436.         lodsw
  437.         jmp     .quit
  438.     @@:
  439.         cmp     ax, TIFF.IFDE_TYPE.LONG
  440.         jne     @f
  441.         lodsd
  442.         lodsd_
  443.         mov     [ebx + tiff_extra.image_height], eax
  444.         jmp     .quit
  445.     @@:
  446.         jmp     .quit
  447.  
  448.   .tag_102:                                             ; BitsPerSample
  449.         lodsd_
  450.         imul    eax, TIFF.IFDE_TYPE_LENGTH.SHORT
  451.         cmp     eax, 4
  452.         ja      @f
  453.         xor     eax, eax
  454.         lodsw_
  455.         mov     [ebx + tiff_extra.bits_per_sample], eax
  456.         lodsw
  457.         jmp     .quit
  458.     @@:
  459.         lodsd_
  460.         add     eax, [_data]
  461.         push    esi
  462.         mov     esi, eax
  463.         xor     eax, eax
  464.         lodsw_
  465.         pop     esi
  466.         mov     [ebx + tiff_extra.bits_per_sample], eax
  467.         jmp     .quit
  468.  
  469.   .tag_103:                                             ; Compression
  470.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  471.         jne     @f
  472.         lodsd
  473.         xor     eax, eax
  474.         lodsw_
  475.         mov     [ebx + tiff_extra.compression], eax
  476.         lodsw
  477.         jmp     .quit
  478.     @@:
  479.         jmp     .quit
  480.  
  481.   .tag_106:                                             ; PhotometricInterpretation
  482.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  483.         jne     @f
  484.         lodsd
  485.         xor     eax, eax
  486.         lodsw_
  487.         mov     [ebx + tiff_extra.photometric], eax
  488.         lodsw
  489.         jmp     .quit
  490.     @@:
  491.  
  492.         jmp     .quit
  493.  
  494.   .tag_111:                                             ; StripOffsets
  495.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  496.         jne     @f
  497.         mov     [ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  498.         jmp     .tag_111.common
  499.     @@:
  500.         mov     [ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.LONG
  501.   .tag_111.common:
  502.         lodsd_
  503.         mov     [ebx + tiff_extra.offsets_number], eax
  504.         imul    eax, [ebx+tiff_extra.strip_offsets_length]
  505.         cmp     eax, 4
  506.         ja      @f
  507.         mov     [ebx + tiff_extra.strip_offsets], esi
  508.         lodsd
  509.         jmp     .quit
  510.     @@:
  511.         lodsd_
  512.         add     eax, [_data]
  513.         mov     [ebx + tiff_extra.strip_offsets], eax
  514.         jmp     .quit
  515.  
  516.   .tag_115:                                             ; SamplesPerPixel
  517.         lodsd_
  518.         imul    eax, TIFF.IFDE_TYPE_LENGTH.SHORT
  519.         cmp     eax, 4
  520.         ja      @f
  521.         xor     eax, eax
  522.         lodsw_
  523.         mov     [ebx + tiff_extra.samples_per_pixel], eax
  524.         lodsw
  525.         jmp     .quit
  526.     @@:
  527.         lodsd_
  528.         add     eax, [_data]
  529.         movzx   eax, word[eax]
  530.         jmp     .quit
  531.  
  532.   .tag_116:                                             ; RowsPerStrip
  533.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  534.         jne     @f
  535.         lodsd
  536.         xor     eax, eax
  537.         lodsw_
  538.         mov     [ebx + tiff_extra.rows_per_strip], eax
  539.         lodsw
  540.         jmp     .quit
  541.     @@:
  542.         lodsd
  543.         lodsd_
  544.         mov     [ebx + tiff_extra.rows_per_strip], eax
  545.         jmp     .quit
  546.  
  547.   .tag_117:                                             ; StripByteCounts
  548.         cmp     ax, TIFF.IFDE_TYPE.SHORT
  549.         jne     @f
  550.         mov     [ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
  551.         jmp     .tag_117.common
  552.     @@:
  553.         mov     [ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.LONG
  554.   .tag_117.common:
  555.         lodsd_
  556.         imul    eax, [ebx + tiff_extra.strip_byte_counts_length]
  557.         cmp     eax, 4
  558.         ja      @f
  559.         mov     [ebx + tiff_extra.strip_byte_counts], esi
  560.         lodsd
  561.         jmp     .quit
  562.     @@:
  563.         lodsd_
  564.         add     eax, [_data]
  565.         mov     [ebx + tiff_extra.strip_byte_counts], eax
  566.         jmp     .quit
  567.  
  568.   .tag_140:                                             ; ColorMap
  569.         lodsd
  570.         lodsd_
  571.         add     eax, [_data]
  572.         mov     [ebx + tiff_extra.palette], eax
  573.         jmp     .quit
  574.   .tag_152:                                             ; ExtraSamples
  575.         mov     [ebx + tiff_extra.extra_samples], esi
  576.         mov     ecx, [ebx + tiff_extra.extra_samples_number]
  577.         rep     lodsw   ; ignored
  578.         jmp     .quit
  579.  
  580.   .quit:
  581.         pop     edi edx ebx
  582.         ret
  583. endp
  584.  
  585.  
  586. proc tiff._.define_image_type
  587.  
  588.         xor     eax, eax
  589.  
  590.         cmp     [ebx + tiff_extra.photometric], TIFF.PHOTOMETRIC.RGB
  591.         jne     .not_full_color
  592.         mov     eax, -3
  593.         add     eax, [ebx + tiff_extra.samples_per_pixel]
  594.         mov     [ebx + tiff_extra.extra_samples_number], eax
  595.         dec     eax
  596.         jns     @f
  597.         mov     eax, Image.bpp24
  598.         jmp     .quit
  599.     @@:
  600.         dec     eax
  601.         jns     @f
  602.         mov     eax, Image.bpp32
  603. ;       mov     [ebx + tiff_extra.extra_samples_number], 0
  604.         jmp     .quit
  605.     @@:
  606.   .not_full_color:      ; grayscale, indexed, bilevel
  607.         cmp     [ebx + tiff_extra.bits_per_sample], 1
  608.         jg      .not_bilevel
  609.         mov     eax, Image.bpp1
  610.         jmp     .quit
  611.   .not_bilevel:         ; grayscale, indexed
  612.         cmp     [ebx + tiff_extra.palette], 0
  613.         je      .without_palette
  614.         cmp     [ebx + tiff_extra.bits_per_sample], 4
  615.         jne     @f
  616. ;       mov     eax, Image.bpp4
  617.         jmp     .quit
  618.     @@:
  619.         cmp     [ebx + tiff_extra.bits_per_sample], 8
  620.         jne     @f
  621.         mov     eax, Image.bpp8i
  622.         jmp     .quit
  623.     @@:
  624.         jmp     .quit
  625.   .without_palette:     ; grayscale
  626.         mov     eax, -1
  627.         add     eax, [ebx + tiff_extra.samples_per_pixel]
  628.         mov     [ebx + tiff_extra.extra_samples_number], eax
  629.         dec     eax
  630.         jns     @f
  631.         mov     eax, Image.bpp8g
  632.         jmp     .quit
  633.     @@:
  634.         mov     eax, Image.bpp8a
  635.         jmp     .quit
  636.   .quit:
  637.         ret
  638. endp
  639.  
  640.  
  641. proc tiff._.decompress.uncompressed _image
  642.  
  643.         rep     movsb
  644.         ret
  645. endp
  646.  
  647.  
  648. proc tiff._.decompress.packbits _image
  649.  
  650.         push    ebx ecx edx esi
  651.  
  652.         mov     edx, ecx
  653.  
  654.   .decode:
  655.         lodsb
  656.         dec     edx
  657.         cmp     al, 0x7f
  658.         jbe     .different
  659.         cmp     al, 0x80
  660.         jne     .identical
  661.         test    edx, edx
  662.         jz      .quit
  663.         jmp     .decode
  664.  
  665.   .identical:
  666.         neg     al
  667.         inc     al
  668.         movzx   ecx, al
  669.         dec     edx
  670.         lodsb
  671.         rep     stosb
  672.         test    edx, edx
  673.         jnz     .decode
  674.         jmp     .quit
  675.  
  676.   .different:
  677.         movzx   ecx, al
  678.         inc     ecx
  679.         sub     edx, ecx
  680.         rep     movsb
  681.         test    edx, edx
  682.         jnz     .decode
  683.  
  684.   .quit:
  685.         pop     esi edx ecx ebx
  686.         ret
  687. endp
  688.  
  689.  
  690. proc    tiff._.decompress.ccitt1d _image
  691. locals
  692.         current_tree            rd      1
  693.         old_tree                rd      1
  694.         width                   rd      1
  695.         height                  rd      1
  696.         width_left              rd      1
  697.         is_makeup               rd      1
  698. endl
  699.         push    ebx ecx edx esi
  700.         mov     [is_makeup], 0
  701.  
  702.         mov     ebx, [_image]
  703.         push    [ebx + Image.Height]
  704.         pop     [height]
  705.         push    [ebx + Image.Width]
  706.         pop     [width]
  707.  
  708.         mov     edx, esi
  709.   .next_scanline:
  710.         push    [width]
  711.         pop     [width_left]
  712.         dec     [height]
  713.         js      .error
  714.         mov     [current_tree], tiff._.huffman_tree_white.begin
  715.         mov     [old_tree], tiff._.huffman_tree_black.begin
  716.         mov     ebx, 0
  717.         mov     ecx, 8
  718.   .next_run:
  719.         mov     esi, [current_tree]
  720.   .branch:
  721.         lodsd
  722.         btr     eax, 31
  723.         jnc     .not_a_leaf
  724.         cmp     eax, 63
  725.         seta    byte[is_makeup]
  726.         ja      @f
  727.         push    [current_tree]
  728.         push    [old_tree]
  729.         pop     [current_tree]
  730.         pop     [old_tree]
  731.     @@:
  732.         stdcall tiff._.write_run, [width_left], [current_tree]
  733.         mov     [width_left], eax
  734.         test    byte[is_makeup], 0x01
  735.         jnz     .next_run
  736.         test    eax, eax
  737.         jnz     .next_run
  738.         jmp     .next_scanline
  739.   .not_a_leaf:
  740.         test    bh, bh
  741.         jnz     @f
  742.         mov     bl, byte[edx]
  743.         inc     edx
  744.         mov     bh, 8
  745.     @@:
  746.         test    al, 0x02
  747.         jz      .not_a_corner
  748.         dec     bh
  749.         sal     bl, 1
  750.         lahf
  751.         and     ah, 0x03
  752.         cmp     al, ah
  753.         jne     .error
  754.         mov     esi, [esi]
  755.         jmp     .branch
  756.   .not_a_corner:
  757.         lodsd
  758.         dec     bh
  759.         sal     bl, 1
  760.         jc      .branch
  761.         mov     esi, eax
  762.         jmp     .branch
  763.   .error:
  764.   .quit:
  765.         pop     esi edx ecx ebx
  766.         ret
  767. endp
  768.  
  769.  
  770. proc    tiff._.write_run _width_left, _current_tree
  771.  
  772.         push    ebx
  773.  
  774.         test    eax, eax
  775.         jz      .done
  776.         sub     [_width_left], eax
  777.         js      .error
  778.         cmp     esi, tiff._.huffman_tree_black.begin
  779.         seta    bh
  780.  
  781.         cmp     ecx, eax
  782.         ja      .one_byte
  783.   .many_bytes:
  784.         mov     bl, [edi]
  785.     @@:
  786.         shl     bl, 1
  787.         or      bl, bh
  788.         dec     eax
  789.         dec     ecx
  790.         jnz     @b
  791.         mov     [edi], bl
  792.         inc     edi
  793.         mov     ecx, eax
  794.         and     eax, 0x07
  795.         shr     ecx, 3
  796.  
  797.         push    eax
  798.         xor     eax, eax
  799.         test    bh, bh
  800.         jz      @f
  801.         dec     al
  802.     @@:
  803.         rep     stosb
  804.         pop     eax
  805.  
  806.         mov     ecx, 8
  807.         test    eax, eax
  808.         jz      .done
  809.  
  810.   .one_byte:
  811.         mov     bl, [edi]
  812.     @@:
  813.         shl     bl, 1
  814.         or      bl, bh
  815.         dec     ecx
  816.         dec     eax
  817.         jnz     @b
  818.         mov     byte[edi], bl
  819.  
  820.         cmp     [_width_left], 0
  821.         jne     .done
  822.         mov     bl, [edi]
  823.         shl     bl, cl
  824.         mov     byte[edi], bl
  825.         inc     edi
  826.   .done:
  827.         mov     eax, [_width_left]
  828.         jmp     .quit
  829.   .error:
  830.   .quit:
  831.         pop     ebx
  832.         ret
  833. endp
  834.  
  835.  
  836. proc    tiff._.get_word _endianness
  837.  
  838.         lodsw
  839.         test    [_endianness], 1
  840.         jnz     @f
  841.         ret
  842.     @@:
  843.         xchg    al, ah
  844.         ret
  845. endp
  846.  
  847.  
  848. proc    tiff._.get_dword _endianness
  849.  
  850.         lodsd
  851.         test    [_endianness], 1
  852.         jnz     @f
  853.         ret
  854.     @@:
  855.         bswap   eax
  856.         ret
  857.  
  858.         ret
  859. endp
  860.  
  861.  
  862. proc    tiff._.pack_8a _img
  863.         mov     ebx, [_img]
  864.         mov     esi, [ebx + Image.Data]
  865.         mov     edi, esi
  866.         mov     ecx, [ebx + Image.Width]
  867.         imul    ecx, [ebx + Image.Height]
  868.     @@:
  869.         lodsw
  870.         stosb
  871.         dec     ecx
  872.         jnz     @b
  873.         ret
  874. endp
  875.  
  876. ;;================================================================================================;;
  877. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  878. ;;================================================================================================;;
  879. ;! Below is private data you should never use directly from your code                             ;;
  880. ;;================================================================================================;;
  881. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  882. ;;================================================================================================;;
  883. tiff.IFDE_tag_table.begin:
  884.   .tag_100:             dd      0x0100, tiff._.parse_IFDE.tag_100               ; image width
  885.   .tag_101:             dd      0x0101, tiff._.parse_IFDE.tag_101               ; image height (this is called 'length' in spec)
  886.   .tag_102:             dd      0x0102, tiff._.parse_IFDE.tag_102               ; bits per sample
  887.   .tag_103:             dd      0x0103, tiff._.parse_IFDE.tag_103               ; compression
  888.   .tag_106:             dd      0x0106, tiff._.parse_IFDE.tag_106               ; photometric interpretation
  889.   .tag_111:             dd      0x0111, tiff._.parse_IFDE.tag_111               ; strip offsets
  890.   .tag_115:             dd      0x0115, tiff._.parse_IFDE.tag_115               ; samples per pixel
  891.   .tag_116:             dd      0x0116, tiff._.parse_IFDE.tag_116               ; rows per strip
  892.   .tag_117:             dd      0x0117, tiff._.parse_IFDE.tag_117               ; strip byte counts
  893.   .tag_140:             dd      0x0140, tiff._.parse_IFDE.tag_140               ; color map
  894.   .tag_152:             dd      0x0152, tiff._.parse_IFDE.tag_152               ; extra samples
  895. tiff.IFDE_tag_table.end:
  896.  
  897. include 'huffman.asm'           ; huffman trees for ccitt1d compression method
  898.