Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ;*****************************************************************************
  2. ; JPEG to RAW convert plugin - for zSea image viewer
  3. ; Copyright (c) 2008, 2009, Evgeny Grechnikov aka Diamond
  4. ; All rights reserved.
  5. ;
  6. ; Redistribution and use in source and binary forms, with or without
  7. ; modification, are permitted provided that the following conditions are met:
  8. ;        * Redistributions of source code must retain the above copyright
  9. ;          notice, this list of conditions and the following disclaimer.
  10. ;        * Redistributions in binary form must reproduce the above copyright
  11. ;          notice, this list of conditions and the following disclaimer in the
  12. ;          documentation and/or other materials provided with the distribution.
  13. ;        * Neither the name of the <organization> nor the
  14. ;          names of its contributors may be used to endorse or promote products
  15. ;          derived from this software without specific prior written permission.
  16. ;
  17. ; THIS SOFTWARE IS PROVIDED BY Evgeny Grechnikov ''AS IS'' AND ANY
  18. ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. ; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
  21. ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26. ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. ;*****************************************************************************
  28. ; Some small changes (c) 2011 Marat Zakiyanov aka Mario79, aka Mario
  29. ;*****************************************************************************
  30.  
  31. format MS COFF
  32.  
  33. public EXPORTS
  34.  
  35. section '.flat' code readable align 16
  36.  
  37. START:
  38.         pushad
  39.         finit
  40.         mov     eax,dword [esp+36]
  41.         mov     esi, [eax]      ; esi -> JPEG data
  42.         mov     ebp, [eax+12]   ; ebp = file size
  43.         mov     [_esp], esp
  44. ; initialize constant tables, if not yet
  45.         cmp     [color_table_1+4], 0
  46.         jnz     @f
  47.         call    initialize_color_table
  48. @@:
  49.         xor     ebx, ebx        ; ebx -> RAW data, not allocated yet
  50.         mov     [dct_buffer], ebx
  51.         mov     [_ebx], ebx
  52. ; check for SOI [Start-Of-Image] marker
  53.         call    get_marker
  54.         jc      .end
  55.         cmp     al, 0xD8        ; SOI?
  56.         jz      .soi_ok
  57. .end:
  58. ; general exit from the function
  59. ; for progressive mode: convert loaded DCT coefficients to image
  60.         call    handle_progressive
  61. ; convert full-color images to RGB
  62.         call    convert_to_rgb
  63.         xor     eax, eax
  64.         test    ebx, ebx
  65.         jnz     @f
  66.         inc     eax     ; ebx=0 => bad image
  67. @@:
  68. .ret:
  69.         mov     ecx, [esp+28]
  70.         mov     [ecx+4], ebx    ; save RAW data ptr
  71.         mov     [ecx+8], eax    ; save result
  72.         popad
  73.         ret     4
  74. .soi_ok:
  75.         mov     [restart_interval], ebx
  76.         mov     [adobe_ycck], 0
  77. ; loop until start of frame (real data), parse markers
  78. .markers_loop:
  79.         call    get_marker
  80.         jc      .end
  81. ; markers RSTn do not have parameters
  82. ; N.B. They can not exist in this part of JPEG, but let's be liberal :)
  83.         cmp     al, 0xD0
  84.         jb      @f
  85.         cmp     al, 0xD8
  86.         jb      .markers_loop
  87. @@:
  88.         cmp     al, 0xD9        ; EOI? [invalid here]
  89.         jz      .end
  90. ; ok, this is marker segment
  91. ; first word is length of the segment
  92.         cmp     ebp, 2
  93.         jb      .end
  94.         xor     edx, edx
  95.         mov     dl, [esi+1]
  96.         mov     dh, [esi]       ; edx = marker length, al = marker value
  97.         sub     ebp, edx
  98.         jb      .end
  99.         cmp     al, 0xDB        ; DQT?
  100.         jz      .dqt
  101.         cmp     al, 0xC4        ; DHT?
  102.         jz      .dht
  103.         cmp     al, 0xCC        ; DAC? [ignored - no arithmetic coding]
  104.         jz      .next_marker
  105.         cmp     al, 0xDD        ; DRI?
  106.         jz      .dri
  107.         cmp     al, 0xDA        ; SOS?
  108.         jz      .sos
  109.         cmp     al, 0xC0
  110.         jb      @f
  111.         cmp     al, 0xD0
  112.         jb      .sofn
  113. @@:
  114.         cmp     al, 0xEE        ; APP14?
  115.         jz      .app14
  116. ; unrecognized marker; let's skip it and hope for the best
  117. .next_marker:
  118.         add     esi, edx
  119.         jmp     .markers_loop
  120. .app14:
  121. ; check for special Adobe marker
  122.         cmp     dx, 14
  123.         jb      .next_marker
  124.         cmp     byte [esi+2], 'A'
  125.         jnz     .next_marker
  126.         cmp     dword [esi+3], 'dobe'
  127.         jnz     .next_marker
  128.         cmp     byte [esi+13], 2
  129.         setz    [adobe_ycck]
  130.         jmp     .next_marker
  131. .dqt:
  132. ; DQT marker found
  133. ; length: 2 bytes for length field + 65 bytes per table
  134.         sub     edx, 2
  135.         jc      .end
  136.         lodsw
  137. .dqt_loop:
  138.         test    edx, edx
  139.         jz      .markers_loop
  140.         sub     edx, 1+64
  141.         jc      .end
  142.         lodsb
  143. ; 8-bit DCT-based process shall not use a 16-bit precision quantization table.
  144.         test    al, 0xF0
  145.         jnz     .end
  146.         and     eax, 3
  147.         mov     [eax+quant_tables_defined], 1
  148.         shl     eax, 8
  149.         lea     edi, [eax+quant_tables]
  150.         xor     ecx, ecx
  151. @@:
  152.         xor     eax, eax
  153.         lodsb
  154.         push    eax
  155.         fild    dword [esp]
  156.         pop     eax
  157.         movzx   eax, byte [zigzag+ecx]
  158.         add     eax, eax
  159.         push    eax
  160.         and     eax, 7*4
  161.         fmul    dword [idct_pre_table+eax]
  162.         pop     eax
  163.         push    eax
  164.         shr     eax, 3
  165.         and     eax, 7*4
  166.         fmul    dword [idct_pre_table+eax]
  167.         pop     eax
  168.         fstp    dword [edi+eax]
  169.         inc     ecx
  170.         cmp     ecx, 64
  171.         jb      @b
  172.         jmp     .dqt_loop
  173. .dri:
  174. ; DRI marker found
  175.         cmp     edx, 4          ; length must be 4
  176.         jnz     .end2
  177.         movzx   eax, word [esi+2]
  178.         xchg    al, ah
  179.         mov     [restart_interval], eax
  180.         jmp     .next_marker
  181. .dht:
  182. ; DHT marker found
  183.         sub     edx, 2
  184.         jc      .end2
  185.         lodsw
  186. .dht_loop:
  187.         test    edx, edx
  188.         jz      .markers_loop
  189.         sub     edx, 17
  190.         jc      .end2
  191. ; next Huffman table; find place for it
  192.         lodsb
  193.         mov     edi, eax
  194.         and     eax, 0x10
  195.         and     edi, 3
  196.         shr     eax, 2
  197.         or      edi, eax
  198.         mov     [dc_huffman_defined+edi], 1
  199. ;       shl     edi, 11
  200.         imul    edi, max_hufftable_size
  201.         add     edi, dc_huffman ; edi -> destination table
  202. ; get table size
  203.         xor     eax, eax
  204.         push    16
  205.         pop     ecx
  206. @@:
  207.         add     al, [esi]
  208.         adc     ah, 0
  209.         inc     esi
  210.         loop    @b
  211.         cmp     ax, 0x100
  212.         ja      .end2
  213.         sub     edx, eax
  214.         jc      .end2
  215. ; construct Huffman tree
  216.         push    ebx edx
  217.         ; lea   eax, [edi+256*8]
  218.         ; push  eax
  219.         ; push  16
  220.         ; mov   edx, esi
  221. ; @@:
  222.         ; cmp   byte [edx-1], 0
  223.         ; jnz   @f
  224.         ; dec   edx
  225.         ; dec   dword [esp]
  226.         ; jmp   @b
  227. ; @@:
  228.         ; sub   edx, [esp]
  229.         ; lea   eax, [edi+8]
  230.         ; push  2
  231.         ; pop   ecx
  232. ; .lenloop:
  233.         ; mov   bl, byte [edx]
  234.         ; test  bl, bl
  235.         ; jz    .len1done
  236.         ; push  eax
  237.         ; xor   eax, eax
  238. ; .len1loop:
  239.         ; dec   ecx
  240.         ; js    .dhterr
  241.         ; cmp   edi, [esp+8]
  242.         ; jae   .dhterr
  243.         ; lodsb
  244.         ; stosd
  245.         ; dec   bl
  246.         ; jnz   .len1loop
  247.         ; pop   eax
  248. ; .len1done:
  249.         ; jecxz .len2done
  250.         ; push  ecx
  251. ; .len2loop:
  252.         ; cmp   eax, [esp+8]
  253.         ; jb    @f
  254.         ; or    eax, -1
  255. ; @@:
  256.         ; cmp   edi, [esp+8]
  257.         ; jae   .dhterr
  258.         ; stosd
  259.         ; add   eax, 8
  260.         ; jnb   @f
  261.         ; or    eax, -1
  262. ; @@:
  263.         ; loop  .len2loop
  264.         ; pop   ecx
  265. ; .len2done:
  266.         ; add   ecx, ecx
  267.         ; inc   edx
  268.         ; dec   dword [esp]
  269.         ; jnz   .lenloop
  270.         ; pop   eax
  271.         ; pop   eax
  272.         ; sub   eax, edi
  273.         ; shr   eax, 2
  274.         ; cmp   eax, ecx
  275.         ; ja    @f
  276.         ; mov   ecx, eax
  277. ; @@:
  278.         ; or    eax, -1
  279.         ; rep   stosd
  280.         ; pop   edx ebx
  281.         ; jmp   .dht_loop
  282. ; .dhterr:
  283.         ; ;pop  eax eax eax edx ebx
  284.         ; add   esp, 5*4
  285.         lea     eax, [edi+256*2]
  286.         push    eax
  287.         lea     edx, [esi-16]
  288.         mov     ah, 1
  289.         mov     ecx, 128
  290. .dht_l1:
  291.         movzx   ebx, byte [edx]
  292.         inc     edx
  293.         test    ebx, ebx
  294.         jz      .dht_l3
  295. .dht_l2:
  296.         cmp     edi, [esp]
  297.         jae     .dhterr1
  298.         lodsb
  299.         xchg    al, ah
  300.         push    ecx
  301.         rep     stosw
  302.         pop     ecx
  303.         xchg    al, ah
  304.         dec     ebx
  305.         jnz     .dht_l2
  306. .dht_l3:
  307.         inc     ah
  308.         shr     ecx, 1
  309.         jnz     .dht_l1
  310.         push    edi
  311.         mov     edi, [esp+4]
  312.         push    edi
  313.         mov     eax, 0x00090100
  314.         mov     cl, 8
  315. .dht_l4:
  316.         movzx   ebx, byte [edx]
  317.         inc     edx
  318.         test    ebx, ebx
  319.         jz      .dht_l6
  320. .dht_l5:
  321.         cmp     edi, [esp]
  322.         jb      @f
  323.         mov     edi, [esp+4]
  324.         rol     eax, 16
  325.         cmp     edi, [esp+8]
  326.         jae     .dhterr2
  327.         stosw
  328.         inc     ah
  329.         mov     [esp+4], edi
  330.         pop     edi
  331.         push    edi
  332.         rol     eax, 16
  333.         add     dword [esp], 16*2
  334. @@:
  335.         lodsb
  336.         xchg    al, ah
  337.         push    ecx
  338.         rep     stosw
  339.         pop     ecx
  340.         xchg    al, ah
  341.         dec     ebx
  342.         jnz     .dht_l5
  343. .dht_l6:
  344.         inc     ah
  345.         shr     ecx, 1
  346.         jnz     .dht_l4
  347.         push    edi
  348.         movzx   ebx, byte [edx]
  349.         add     ebx, ebx
  350.         add     bl, [edx+1]
  351.         adc     bh, 0
  352.         add     ebx, ebx
  353.         add     bl, [edx+2]
  354.         adc     bh, 0
  355.         add     ebx, ebx
  356.         add     bl, [edx+3]
  357.         adc     bh, 0
  358.         add     ebx, 15
  359.         shr     ebx, 4
  360.         mov     cl, 8
  361.         lea     ebx, [edi+ebx*2]
  362.         sub     ebx, [esp+12]
  363.         add     ebx, 31
  364.         shr     ebx, 5
  365.         mov     edi, ebx
  366.         shl     edi, 5
  367.         add     edi, [esp+12]
  368.         xor     ebx, 9
  369.         shl     ebx, 16
  370.         xor     eax, ebx
  371.         push    edi
  372. .dht_l7:
  373.         movzx   ebx, byte [edx]
  374.         inc     edx
  375.         test    ebx, ebx
  376.         jz      .dht_l10
  377. .dht_l8:
  378.         cmp     edi, [esp]
  379.         jb      .dht_l9
  380.         mov     edi, [esp+4]
  381.         cmp     edi, [esp+8]
  382.         jb      @f
  383.         mov     edi, [esp+12]
  384.         cmp     edi, [esp+16]
  385.         jae     .dhterr3
  386.         mov     al, 9
  387.         stosb
  388.         rol     eax, 8
  389.         stosb
  390.         inc     eax
  391.         ror     eax, 8
  392.         mov     [esp+12], edi
  393.         mov     edi, [esp+8]
  394.         add     dword [esp+8], 16*2
  395. @@:
  396.         mov     al, 9
  397.         stosb
  398.         rol     eax, 16
  399.         stosb
  400.         inc     eax
  401.         ror     eax, 16
  402.         mov     [esp+4], edi
  403.         pop     edi
  404.         push    edi
  405.         add     dword [esp], 16*2
  406. .dht_l9:
  407.         lodsb
  408.         xchg    al, ah
  409.         push    ecx
  410.         rep     stosw
  411.         pop     ecx
  412.         xchg    al, ah
  413.         dec     ebx
  414.         jnz     .dht_l8
  415. .dht_l10:
  416.         inc     ah
  417.         shr     ecx, 1
  418.         jnz     .dht_l7
  419.         push    -1
  420.         pop     eax
  421.         pop     ecx
  422.         sub     ecx, edi
  423.         rep     stosb
  424.         pop     edi
  425.         pop     ecx
  426.         sub     ecx, edi
  427.         rep     stosb
  428.         pop     edi
  429.         pop     ecx
  430.         sub     ecx, edi
  431.         rep     stosb
  432.         pop     edx ebx
  433.         jmp     .dht_loop
  434. .dhterr3:
  435.         pop     eax eax
  436. .dhterr2:
  437.         pop     eax eax
  438. .dhterr1:
  439.         pop     eax
  440.         pop     edx ebx
  441. .end2:
  442.         jmp     .end
  443. .sofn:
  444. ; SOFn marker found
  445.         test    ebx, ebx
  446.         jnz     .end2   ; only one frame is allowed
  447. ; only SOF0 [baseline sequential], SOF1 [extended sequential], SOF2 [progressive]
  448. ; nobody supports other compression methods
  449.         cmp     al, 0xC2
  450.         ja      .end2
  451.         setz    [progressive]
  452. ; Length must be at least 8
  453.         sub     edx, 8
  454.         jb      .end2
  455. ; Sample precision in JFIF must be 8 bits
  456.         cmp     byte [esi+2], 8
  457.         jnz     .end2
  458. ; Color space in JFIF is either YCbCr (color images, 3 components)
  459. ;                        or Y (grey images, 1 component)
  460.         movzx   eax, byte [esi+7]
  461.         cmp     al, 1
  462.         jz      @f
  463.         cmp     al, 3
  464.         jz      @f
  465. ; Adobe products sometimes use YCCK color space with 4 components
  466.         cmp     al, 4
  467.         jnz     .end2
  468.         cmp     [adobe_ycck], 0
  469.         jz      .end2
  470. @@:
  471.         mov     edi, eax        ; edi = number of components
  472.         lea     eax, [eax*3]
  473.         sub     edx, eax
  474.         jnz     .end2
  475. ; get width and height
  476. ; width must be nonzero
  477. ; height must be nonzero - nobody supports DNL markers
  478.         mov     ah, [esi+3]
  479.         mov     al, [esi+4]     ; eax = height
  480.         test    eax, eax
  481.         jz      .end2
  482.         xor     ecx, ecx
  483.         mov     ch, [esi+5]
  484.         mov     cl, [esi+6]     ; ecx = width
  485.         jecxz   .end3
  486.         push    eax ecx
  487.         imul    ecx, eax
  488.         cmp     ecx, 4000000h
  489.         jb      @f
  490.         pop     ecx eax
  491. .end3:
  492.         jmp     .end2
  493. @@:
  494.         imul    ecx, edi
  495.         push    ecx
  496.         add     ecx, 44+1
  497. ; for grayscale images, allocate additional memory for palette
  498.         cmp     edi, 1
  499.         jnz     @f
  500.         add     ecx, 256*4-1
  501. @@:
  502.         push    68
  503.         pop     eax
  504.         push    12
  505.         pop     ebx
  506.         int     0x40
  507.         mov     ebx, eax
  508.         test    eax, eax
  509.         jnz     @f
  510.         pop     ecx
  511.         mov     al, 2
  512.         jmp     .ret
  513. @@:
  514. ; OS zeroes all allocated memory
  515. ;       push    edx edi
  516. ;       mov     edi, eax
  517. ;       mov     edx, ecx
  518. ;       shr     ecx, 2
  519. ;       xor     eax, eax
  520. ;       rep     stosd
  521. ;       mov     ecx, edx
  522. ;       and     ecx, 3
  523. ;       rep     stosb
  524. ;       mov     ecx, edx
  525. ;       pop     edi edx
  526.         mov     [_ebx], ebx
  527.         pop     dword [ebx+32]          ; size of pixels area
  528.         push    44
  529.         pop     eax
  530.         mov     dword [ebx+28], eax     ; pointer to RGB data
  531. ; create grayscale palette if needed
  532.         cmp     edi, 1
  533.         jnz     .no_create_palette
  534.         mov     dword [ebx+20], eax
  535.         mov     ecx, 256*4
  536.         mov     dword [ebx+24], ecx
  537.         add     dword [ebx+28], ecx
  538.         push    edi
  539.         shr     ecx, 2
  540.         xor     eax, eax
  541.         lea     edi, [ebx+44]
  542. @@:
  543.         stosd
  544.         add     eax, 0x010101
  545.         loop    @b
  546.         pop     edi
  547. .no_create_palette:
  548. ; other image characteristics
  549.         pop     ecx eax
  550.         mov     dword [ebx], 'RAW '     ; signature
  551.         mov     dword [ebx+4], ecx      ; width
  552.         mov     dword [ebx+8], eax      ; height
  553.         mov     eax, edi
  554.         shl     eax, 3
  555.         mov     dword [ebx+12], eax     ; total pixel size
  556.         mov     byte [ebx+16], 8        ; 8 bits per component
  557.         mov     word [ebx+18], di       ; number of components
  558.         mov     [delta_x], eax
  559.         mov     [pixel_size], edi
  560.         ;mov    eax, edi
  561.         imul    eax, ecx
  562.         mov     [delta_y], eax
  563.         shr     eax, 3
  564.         mov     [line_size], eax
  565. ;       and     dword [ebx+36], 0       ; transparency data pointer = NULL
  566. ;       and     dword [ebx+40], 0       ; transparency data size
  567.         add     esi, 8
  568.         mov     ecx, edi
  569.         mov     edi, components
  570.         xor     eax, eax
  571.         xor     edx, edx
  572. .sof_parse_comp:
  573.         movsb   ; db ComponentIdentifier
  574.         lodsb
  575.         mov     ah, al
  576.         and     al, 0xF
  577.         jz      .end3
  578.         shr     ah, 4
  579.         jz      .end3
  580.         stosd   ; db V, db H, db ?, db ? (will be filled later)
  581.         cmp     dl, al
  582.         ja      @f
  583.         mov     dl, al
  584. @@:
  585.         cmp     dh, ah
  586.         ja      @f
  587.         mov     dh, ah
  588. @@:
  589.         movsb   ; db QuantizationTableID
  590.         loop    .sof_parse_comp
  591.         mov     word [max_v], dx
  592.         movzx   eax, dh
  593.         movzx   edx, dl
  594.         push    eax edx
  595.         shl     eax, 3
  596.         shl     edx, 3
  597.         mov     [block_width], eax
  598.         mov     [block_height], edx
  599.         pop     edx eax
  600.         push    eax edx
  601.         imul    eax, [delta_x]
  602.         mov     [block_delta_x], eax
  603.         imul    edx, [delta_y]
  604.         mov     [block_delta_y], edx
  605.         mov     eax, [ebx+4]
  606.         add     eax, [block_width]
  607.         dec     eax
  608.         xor     edx, edx
  609.         div     [block_width]
  610.         mov     [x_num_blocks], eax
  611.         mov     eax, [ebx+8]
  612.         add     eax, [block_height]
  613.         dec     eax
  614.         xor     edx, edx
  615.         div     [block_height]
  616.         mov     [y_num_blocks], eax
  617.         mov     cl, [ebx+18]
  618.         pop     edx
  619.         mov     edi, components
  620. @@:
  621.         mov     eax, edx
  622.         div     byte [edi+1]    ; VMax / V_i = VFactor_i
  623.         mov     byte [edi+3], al        ; db VFactor
  624.         pop     eax
  625.         push    eax
  626.         div     byte [edi+2]    ; HMax / H_i = HFactor_i
  627.         mov     byte [edi+4], al        ; db HFactor
  628.         add     edi, 6
  629.         loop    @b
  630.         pop     eax
  631.         cmp     [progressive], 0
  632.         jz      .sof_noprogressive
  633.         mov     eax, [x_num_blocks]
  634.         mul     [block_width]
  635.         mul     [y_num_blocks]
  636.         mul     [block_height]
  637.         add     eax, eax
  638.         mov     [dct_buffer_size], eax
  639.         mul     [pixel_size]
  640.         xchg    eax, ecx
  641.         push    ebx
  642.         push    68
  643.         pop     eax
  644.         push    12
  645.         pop     ebx
  646.         int     0x40
  647.         pop     ebx
  648.         test    eax, eax
  649.         jnz     @f
  650.         mov     ecx, ebx
  651.         push    68
  652.         pop     eax
  653.         push    13
  654.         pop     ebx
  655.         int     0x40
  656.         xor     ebx, ebx
  657.         jmp     .end
  658. @@:
  659.         mov     [dct_buffer], eax
  660. .sof_noprogressive:
  661.         jmp     .markers_loop
  662. .sos:
  663. ; SOS marker found
  664. ; frame must be already opened
  665.         test    ebx, ebx
  666.         jz      .end3
  667.         cmp     edx, 6
  668.         jb      .end3
  669. ; parse marker
  670.         movzx   eax, byte [esi+2]       ; number of components in this scan
  671.         test    eax, eax
  672.         jz      .end3           ; must be nonzero
  673.         cmp     al, [ebx+18]
  674.         ja      .end3           ; must be <= total number of components
  675. ;       mov     [ns], eax
  676.         cmp     al, 1
  677.         setz    [not_interleaved]
  678.         lea     ecx, [6+eax+eax]
  679.         cmp     edx, ecx
  680.         jnz     .end3
  681.         mov     ecx, eax
  682.         mov     edi, cur_components
  683.         add     esi, 3
  684. .sos_find_comp:
  685.         lodsb   ; got ComponentID, look for component info
  686.         push    ecx esi
  687.         mov     cl, [ebx+18]
  688.         mov     esi, components
  689.         and     dword [edi+48], 0
  690.         and     dword [edi+52], 0
  691. @@:
  692.         cmp     [esi], al
  693.         jz      @f
  694.         inc     dword [edi+52]
  695.         add     esi, 6
  696.         loop    @b
  697. @@:
  698.         mov     eax, [esi+1]
  699.         mov     dl, [esi+5]
  700.         pop     esi ecx
  701.         jnz     .end3   ; bad ComponentID
  702.         cmp     [not_interleaved], 0
  703.         jz      @f
  704.         mov     ax, 0x0101
  705. @@:
  706.         stosd           ; db V, db H, db VFactor, db HFactor
  707.         xor     eax, eax
  708.         mov     al, byte [edi-1]        ; get HFactor
  709.         mul     byte [ebx+18]           ; number of components
  710.         stosd                   ; HIncrement_i = HFactor_i * sizeof(pixel)
  711.         mov     al, byte [edi-4-2]      ; get VFactor
  712.         mul     byte [ebx+18]           ; number of components
  713.         imul    eax, [ebx+4]            ; image width
  714.         stosd                   ; VIncrement_i = VFactor_i * sizeof(row)
  715.         xchg    eax, edx
  716.         and     eax, 3
  717.         cmp     [quant_tables_defined+eax], 0
  718.         jz      .end3
  719.         shl     eax, 8
  720.         add     eax, quant_tables
  721.         stosd           ; dd QuantizationTable
  722.         lodsb
  723.         movzx   eax, al
  724.         mov     edx, eax
  725.         shr     eax, 4
  726.         and     edx, 3
  727.         and     eax, 3
  728.         cmp     [dc_huffman_defined+eax], 0
  729.         jnz     .dc_table_ok
  730.         cmp     [progressive], 0
  731.         jz      .end3
  732.         xor     eax, eax
  733.         jmp     .dc_table_done
  734. .dc_table_ok:
  735. ;       shl     eax, 11
  736.         imul    eax, max_hufftable_size
  737.         add     eax, dc_huffman
  738. .dc_table_done:
  739.         cmp     [ac_huffman_defined+edx], 0
  740.         jnz     .ac_table_ok
  741.         cmp     [progressive], 0
  742.         jz      .end3
  743.         xor     edx, edx
  744.         jmp     .ac_table_done
  745. .ac_table_ok:
  746. ;       shl     edx, 11
  747.         imul    edx, max_hufftable_size
  748.         add     edx, ac_huffman
  749. .ac_table_done:
  750.         stosd           ; dd DCTable
  751.         xchg    eax, edx
  752.         stosd           ; dd ACTable
  753.         push    ecx
  754.         mov     eax, [ebx+4]
  755.         movzx   ecx, byte [edi-21]      ; get HFactor
  756.         cdq     ; edx:eax = width (width<0x10000, so as dword it is unsigned)
  757.         div     ecx
  758.         stosd           ; dd width / HFactor_i
  759.         stosd
  760.         xchg    eax, ecx
  761.         inc     eax
  762.         sub     eax, edx
  763.         stosd           ; dd HFactor_i+1 - (width % HFactor_i)
  764.         mov     eax, [ebx+8]
  765.         movzx   ecx, byte [edi-34]      ; get VFactor
  766.         cdq
  767.         div     ecx
  768.         stosd           ; dd height / VFactor_i
  769.         stosd
  770.         xchg    eax, ecx
  771.         inc     eax
  772.         sub     eax, edx
  773.         stosd           ; dd VFactor_i+1 - (height % VFactor_i)
  774.         pop     ecx
  775.         scasd           ; dd DCPrediction
  776.         cmp     dword [edi], 0
  777.         setnp   al
  778.         ror     al, 1
  779.         mov     byte [edi-1], al
  780.         scasd           ; dd ComponentOffset
  781.         dec     ecx
  782.         jnz     .sos_find_comp
  783.         mov     [cur_components_end], edi
  784.         mov     edi, ScanStart
  785.         movsb
  786.         cmp     byte [esi], 63
  787.         ja      .end3
  788.         movsb
  789.         lodsb
  790.         push    eax
  791.         and     al, 0xF
  792.         stosb
  793.         pop     eax
  794.         shr     al, 4
  795.         stosb
  796. ; now unpack data
  797.         call    init_limits
  798.         and     [decoded_MCUs], 0
  799.         mov     [cur_rst_marker], 7
  800.         and     [huffman_bits], 0
  801.         cmp     [progressive], 0
  802.         jz      .sos_noprogressive
  803. ; progressive mode - only decode DCT coefficients
  804. ; initialize pointers to coefficients data
  805. ; zero number of EOBs for AC coefficients
  806. ; redefine HIncrement and VIncrement
  807.         mov     edi, cur_components
  808. .coeff_init:
  809.         mov     eax, [dct_buffer_size]
  810.         mul     dword [edi+52]
  811.         add     eax, [dct_buffer]
  812.         mov     [edi+12], eax
  813.         and     dword [edi+52], 0
  814.         cmp     [ScanStart], 0
  815.         jz      .scan_dc
  816.         cmp     dword [edi+20], 0
  817.         jz      .end3
  818.         jmp     @f
  819. .scan_dc:
  820.         cmp     dword [edi+16], 0
  821.         jz      .end3
  822. @@:
  823.         movzx   eax, byte [edi+1]
  824.         shl     eax, 7
  825.         mov     [edi+4], eax
  826.         mov     eax, [edi+28]
  827.         mov     cl, [edi+3]
  828.         cmp     cl, [edi+32]
  829.         sbb     eax, -7-1
  830.         shr     eax, 3
  831.         shl     eax, 7
  832.         mov     [edi+8], eax
  833.         add     edi, 56
  834.         cmp     edi, [cur_components_end]
  835.         jb      .coeff_init
  836. ; unpack coefficients
  837. ; N.B. Speed optimization has sense here.
  838.         push    ebx
  839. .coeff_decode_loop:
  840.         mov     edx, cur_components
  841. .coeff_components_loop:
  842.         mov     edi, [edx+12]
  843.         movzx   ecx, byte [edx]
  844.         push    dword [edx+40]
  845.         push    edi
  846. .coeff_y_loop:
  847.         push    ecx
  848.         movzx   eax, byte [edx+1]
  849.         push    dword [edx+28]
  850.         push    edi
  851. .coeff_x_loop:
  852.         cmp     dword [edx+40], 0
  853.         jl      @f
  854.         cmp     dword [edx+28], 0
  855.         jge     .realdata
  856. @@:
  857.         cmp     [not_interleaved], 0
  858.         jnz     .norealdata
  859.         push    eax edi
  860.         mov     edi, dct_coeff
  861.         call    decode_progressive_coeff
  862.         pop     edi eax
  863.         jmp     .norealdata
  864. .realdata:
  865.         push    eax
  866.         call    decode_progressive_coeff
  867.         add     edi, 64*2
  868.         pop     eax
  869. .norealdata:
  870.         sub     dword [edx+28], 8
  871.         sub     eax, 1
  872.         jnz     .coeff_x_loop
  873.         pop     edi
  874.         pop     dword [edx+28]
  875.         add     edi, [edx+8]
  876.         pop     ecx
  877.         sub     dword [edx+40], 8
  878.         sub     ecx, 1
  879.         jnz     .coeff_y_loop
  880.         movzx   eax, byte [edx+1]
  881.         shl     eax, 3
  882.         pop     edi
  883.         add     edi, [edx+4]
  884.         pop     dword [edx+40]
  885.         sub     [edx+28], eax
  886.         mov     [edx+12], edi
  887.         add     edx, 56
  888.         cmp     edx, [cur_components_end]
  889.         jnz     .coeff_components_loop
  890.         call    next_MCU
  891.         jc      .norst
  892.         sub     [cur_x], 1
  893.         jnz     .coeff_decode_loop
  894.         call    next_line
  895.         mov     edx, cur_components
  896. @@:
  897.         mov     eax, [max_x]
  898.         imul    eax, [edx+4]
  899.         sub     [edx+12], eax
  900.         movzx   eax, byte [edx]
  901.         imul    eax, [edx+8]
  902.         add     [edx+12], eax
  903.         add     edx, 56
  904.         cmp     edx, [cur_components_end]
  905.         jnz     @b
  906.         sub     [cur_y], 1
  907.         jnz     .coeff_decode_loop
  908.         pop     ebx
  909.         jmp     .markers_loop
  910. .norst:
  911.         pop     ebx
  912.         jmp     .end4
  913. .sos_noprogressive:
  914. ; normal mode - unpack JPEG image
  915.         mov     edi, [ebx+28]
  916.         add     edi, ebx
  917.         mov     [cur_out_ptr], edi
  918. ; N.B. Speed optimization has sense here.
  919. .decode_loop:
  920.         call    decode_MCU
  921.         call    next_MCU
  922.         jc      .end4
  923.         sub     [cur_x], 1
  924.         jnz     .decode_loop
  925.         call    next_line
  926.         sub     [cur_y], 1
  927.         jnz     .decode_loop
  928.         jmp     .markers_loop
  929. .end4:
  930.         jmp     .end3
  931. ;---------------------------------------------------------------------
  932. get_marker:
  933. ; in: esi -> data
  934. ; out: CF=0, al=marker value - ok
  935. ;      CF=1 - no marker
  936.         sub     ebp, 1
  937.         jc      .ret
  938.         lodsb
  939. if 1
  940.         cmp     al, 0xFF
  941.         jae     @f
  942. ; Some stupid men, which do not read specifications and manuals,
  943. ; sometimes create markers with length field two less than true
  944. ; value (in JPEG length of marker = length of data INCLUDING
  945. ; length field itself). To open such files, allow 2 bytes
  946. ; before next marker.
  947.         cmp     ebp, 2
  948.         jb      .ret
  949.         lodsb
  950.         lodsb
  951. end if
  952.         cmp     al, 0xFF
  953.         jb      .ret
  954. @@:
  955.         sub     ebp, 1
  956.         jc      .ret
  957.         lodsb
  958.         cmp     al, 0xFF
  959.         jz      @b
  960.         clc
  961. .ret:
  962.         ret
  963. ;---------------------------------------------------------------------
  964. align 16
  965. decode_MCU:
  966.         mov     edx, cur_components
  967. .components_loop:
  968. ; decode each component
  969.         push    [cur_out_ptr]
  970.         movzx   ecx, byte [edx]
  971.         push    dword [edx+40]
  972. ; we have H_i * V_i blocks of packed data, decode them
  973. .y_loop_1:
  974.         push    [cur_out_ptr]
  975.         push    ecx
  976.         movzx   eax, byte [edx+1]
  977.         push    dword [edx+28]
  978. .x_loop_1:
  979.         push    eax
  980.         call    decode_data_unit
  981.         cmp     dword [edx+40], 0
  982.         jl      .nocopyloop
  983.         cmp     dword [edx+28], 0
  984.         jl      .nocopyloop
  985. ; now we have decoded block 8*8 in decoded_data
  986. ; H_i * V_i packed blocks 8*8 make up one block (8*HMax) * (8*VMax)
  987. ; so each pixel in packed block corresponds to HFact * VFact pixels
  988.         movzx   ecx, byte [edx+2]
  989.         push    esi ebp
  990.         mov     edi, [cur_out_ptr]
  991.         add     edi, [edx+52]
  992. .y_loop_2:
  993.         push    ecx edi
  994.         cmp     ecx, [edx+44]
  995.         mov     ecx, [edx+40]
  996.         sbb     ecx, 8-1
  997.         sbb     eax, eax
  998.         and     ecx, eax
  999.         add     ecx, 8
  1000.         jz      .skip_x_loop_2
  1001.         movzx   eax, byte [edx+3]
  1002. .x_loop_2:
  1003.         push    eax ecx edi
  1004.         cmp     eax, [edx+32]
  1005.         mov     eax, [edx+28]
  1006.         sbb     eax, 8-1
  1007.         sbb     ebp, ebp
  1008.         and     eax, ebp
  1009.         mov     ebp, .copyiter_all
  1010.         mov     esi, decoded_data
  1011.         sub     ebp, eax
  1012.         sub     ebp, eax
  1013.         sub     ebp, eax
  1014.         mov     eax, [edx+4]
  1015.         sub     eax, 1
  1016. .copyloop:
  1017.         push    esi edi
  1018.         jmp     ebp
  1019. .copyiter_all:
  1020.         movsb
  1021. repeat 7
  1022.         add     edi, eax
  1023.         movsb
  1024. end repeat
  1025.         nop
  1026.         nop
  1027.         pop     edi esi
  1028.         add     edi, [edx+8]
  1029.         add     esi, 8
  1030.         sub     ecx, 1
  1031.         jnz     .copyloop
  1032.         pop     edi ecx eax
  1033.         add     edi, [pixel_size]
  1034.         sub     eax, 1
  1035.         jnz     .x_loop_2
  1036. .skip_x_loop_2:
  1037.         pop     edi ecx
  1038.         add     edi, [line_size]
  1039.         sub     ecx, 1
  1040.         jnz     .y_loop_2
  1041.         pop     ebp esi
  1042. .nocopyloop:
  1043.         mov     eax, [delta_x]
  1044.         add     [cur_out_ptr], eax
  1045.         pop     eax
  1046.         sub     dword [edx+28], 8
  1047.         sub     eax, 1
  1048.         jnz     .x_loop_1
  1049.         pop     dword [edx+28]
  1050.         pop     ecx
  1051.         pop     eax
  1052.         sub     dword [edx+40], 8
  1053.         add     eax, [delta_y]
  1054.         mov     [cur_out_ptr], eax
  1055.         sub     ecx, 1
  1056.         jnz     .y_loop_1
  1057.         movzx   eax, byte [edx+1]
  1058.         pop     dword [edx+40]
  1059.         shl     eax, 3
  1060.         pop     [cur_out_ptr]
  1061.         sub     dword [edx+28], eax
  1062.         add     edx, 56
  1063.         cmp     edx, [cur_components_end]
  1064.         jb      .components_loop
  1065.         mov     eax, [cur_block_dx]
  1066.         add     [cur_out_ptr], eax
  1067.         ret
  1068.  
  1069. align 16
  1070. next_MCU:
  1071.         add     [decoded_MCUs], 1
  1072.         mov     eax, [restart_interval]
  1073.         test    eax, eax
  1074.         jz      .no_restart
  1075.         cmp     [decoded_MCUs], eax
  1076.         jb      .no_restart
  1077.         and     [decoded_MCUs], 0
  1078.         and     [huffman_bits], 0
  1079.         cmp     [cur_x], 1
  1080.         jnz     @f
  1081.         cmp     [cur_y], 1
  1082.         jz      .no_restart
  1083. @@:
  1084. ; restart marker must be present
  1085.         sub     ebp, 2
  1086.         js      .error
  1087.         cmp     byte [esi], 0xFF
  1088.         jnz     .error
  1089.         mov     al, [cur_rst_marker]
  1090.         inc     eax
  1091.         and     al, 7
  1092.         mov     [cur_rst_marker], al
  1093.         add     al, 0xD0
  1094.         cmp     [esi+1], al
  1095.         jnz     .error
  1096.         add     esi, 2
  1097. ; handle restart marker - zero all DC predictions
  1098.         mov     edx, cur_components
  1099. @@:
  1100.         and     word [edx+48], 0
  1101.         add     edx, 56
  1102.         cmp     edx, [cur_components_end]
  1103.         jb      @b
  1104. .no_restart:
  1105.         clc
  1106.         ret
  1107. .error:
  1108.         stc
  1109.         ret
  1110.  
  1111. next_line:
  1112.         mov     eax, [max_x]
  1113.         mov     [cur_x], eax
  1114.         mul     [cur_block_dx]
  1115.         sub     eax, [cur_block_dy]
  1116.         sub     [cur_out_ptr], eax
  1117.         mov     edx, cur_components
  1118. @@:
  1119.         mov     eax, [edx+24]
  1120.         mov     [edx+28], eax
  1121.         movzx   eax, byte [edx]
  1122.         shl     eax, 3
  1123.         sub     [edx+40], eax
  1124.         add     edx, 56
  1125.         cmp     edx, [cur_components_end]
  1126.         jb      @b
  1127.         ret
  1128.  
  1129. init_limits:
  1130.         push    [x_num_blocks]
  1131.         pop     [max_x]
  1132.         push    [y_num_blocks]
  1133.         pop     [max_y]
  1134.         push    [block_delta_x]
  1135.         pop     [cur_block_dx]
  1136.         push    [block_delta_y]
  1137.         pop     [cur_block_dy]
  1138.         cmp     [not_interleaved], 0
  1139.         jz      @f
  1140.         mov     eax, dword [cur_components+28]
  1141.         movzx   ecx, byte [cur_components+3]
  1142.         cmp     cl, [cur_components+32]
  1143.         sbb     eax, -7-1
  1144.         shr     eax, 3
  1145.         mov     [max_x], eax
  1146.         mov     eax, dword [cur_components+40]
  1147.         movzx   edx, byte [cur_components+2]
  1148.         cmp     dl, [cur_components+44]
  1149.         sbb     eax, -7-1
  1150.         shr     eax, 3
  1151.         mov     [max_y], eax
  1152.         imul    ecx, [delta_x]
  1153.         mov     [cur_block_dx], ecx
  1154.         imul    edx, [delta_y]
  1155.         mov     [cur_block_dy], edx
  1156. @@:
  1157.         push    [max_x]
  1158.         pop     [cur_x]
  1159.         push    [max_y]
  1160.         pop     [cur_y]
  1161.         ret
  1162.  
  1163. ;macro get_bit
  1164. ;{
  1165. ;local .l1,.l2,.marker
  1166. ;       add     cl, cl
  1167. ;       jnz     .l1
  1168. ;       sub     ebp, 1
  1169. ;       js      decode_data_unit.eof
  1170. ;       mov     cl, [esi]
  1171. ;       cmp     cl, 0xFF
  1172. ;       jnz     .l2
  1173. ;.marker:
  1174. ;       add     esi, 1
  1175. ;       sub     ebp, 1
  1176. ;       js      decode_data_unit.eof
  1177. ;       cmp     byte [esi], 0xFF
  1178. ;       jz      .marker
  1179. ;       cmp     byte [esi], 0
  1180. ;       jnz     decode_data_unit.eof
  1181. ;.l2:
  1182. ;       sub     esi, -1
  1183. ;       adc     cl, cl
  1184. ;.l1:
  1185. ;}
  1186. macro get_bit
  1187. {
  1188. local .l1,.l2,.marker
  1189.         sub     cl, 1
  1190.         jns     .l1
  1191.         sub     ebp, 1
  1192.         js      .eof
  1193.         mov     ch, [esi]
  1194.         cmp     ch, 0xFF
  1195.         jnz     .l2
  1196. .marker:
  1197.         add     esi, 1
  1198.         sub     ebp, 1
  1199.         js      .eof
  1200.         cmp     byte [esi], 0xFF
  1201.         jz      .marker
  1202.         cmp     byte [esi], 0
  1203.         jnz     .eof
  1204. .l2:
  1205.         add     esi, 1
  1206.         mov     cl, 7
  1207. .l1:
  1208.         add     ch, ch
  1209. }
  1210. macro get_bits restore_edx
  1211. {
  1212. local .l1,.l2,.l3,.marker2
  1213.         movzx   eax, ch
  1214.         mov     dl, cl
  1215.         shl     eax, 24
  1216.         neg     cl
  1217.         push    ebx
  1218.         add     cl, 24
  1219. .l1:
  1220.         cmp     bl, dl
  1221.         jbe     .l2
  1222.         sub     bl, dl
  1223.         sub     ebp, 1
  1224.         js      .eof
  1225.         mov     ch, [esi]
  1226.         cmp     ch, 0xFF
  1227.         jnz     .l3
  1228. .marker2:
  1229.         add     esi, 1
  1230.         sub     ebp, 1
  1231.         js      .eof
  1232.         cmp     byte [esi], 0xFF
  1233.         jz      .marker2
  1234.         cmp     byte [esi], 0
  1235.         jnz     .eof
  1236. .l3:
  1237.         movzx   edx, ch
  1238.         add     esi, 1
  1239.         shl     edx, cl
  1240.         sub     cl, 8
  1241.         or      eax, edx
  1242.         mov     dl, 8
  1243.         jmp     .l1
  1244. .l2:
  1245.         mov     cl, bl
  1246.         sub     dl, bl
  1247.         shl     ch, cl
  1248.         pop     ebx
  1249.         cmp     eax, 80000000h
  1250.         rcr     eax, 1
  1251.         mov     cl, 31
  1252.         sub     cl, bl
  1253.         sar     eax, cl
  1254.         mov     cl, dl
  1255. if restore_edx eq true
  1256.         pop     edx
  1257. end if
  1258.         add     eax, 80000000h
  1259.         adc     eax, 80000000h
  1260. }
  1261. ; macro get_huffman_code
  1262. ; {
  1263. ; local .l1
  1264.         ; xor   ebx, ebx
  1265. ; .l1:
  1266.         ; get_bit
  1267.         ; adc   ebx, ebx
  1268.         ; mov   eax, [eax+4*ebx]
  1269.         ; xor   ebx, ebx
  1270.         ; cmp   eax, -1
  1271.         ; jz    .eof
  1272.         ; cmp   eax, 0x1000
  1273.         ; jae   .l1
  1274.         ; mov   ebx, eax
  1275. ; }
  1276. macro get_huffman_code
  1277. {
  1278. local .l1,.l2,.l3,.l4,.l5,.l6,.nomarker1,.marker1,.nomarker2,.marker2,.nomarker3,.marker3,.done
  1279. ; 1. (First level in Huffman table) Does the current Huffman code fit in 8 bits
  1280. ; and have we got enough bits?
  1281.         movzx   ebx, ch
  1282.         cmp     byte [eax+ebx*2], cl
  1283.         jbe     .l1
  1284. ; 2a. No; load next byte
  1285.         sub     ebp, 1
  1286.         js      .eof
  1287.         mov     ch, [esi]
  1288.         movzx   edx, ch
  1289.         cmp     ch, 0xFF
  1290.         jnz     .nomarker1
  1291. .marker1:
  1292.         add     esi, 1
  1293.         sub     ebp, 1
  1294.         js      .eof
  1295.         cmp     byte [esi], 0xFF
  1296.         jz      .marker1
  1297.         cmp     byte [esi], 0
  1298.         jnz     .eof
  1299. .nomarker1:
  1300.         shr     edx, cl
  1301.         add     esi, 1
  1302.         or      ebx, edx
  1303. ; 3a. (First level in Huffman table, >=8 bits known) Does the current Huffman code fit in 8 bits?
  1304.         cmp     byte [eax+ebx*2], 8
  1305.         jbe     .l2
  1306.         jl      .eof
  1307. ; 4aa. No; go to next level
  1308.         movzx   ebx, byte [eax+ebx*2+1]
  1309.         mov     dl, ch
  1310.         shl     ebx, 5
  1311.         ror     edx, cl
  1312.         lea     ebx, [eax+ebx+0x200]
  1313.         shr     edx, 24
  1314.         push    edx
  1315.         shr     edx, 4
  1316. ; 5aa. (Second level in Huffman table) Does the current Huffman code fit in 12 bits
  1317. ; and have we got enough bits?
  1318.         cmp     byte [ebx+edx*2], cl
  1319.         jbe     .l3
  1320. ; 6aaa. No; have we got 12 bits?
  1321.         cmp     cl, 4
  1322.         jae     .l4
  1323. ; 7aaaa. No; load next byte
  1324.         pop     edx
  1325.         sub     ebp, 1
  1326.         js      .eof
  1327.         mov     ch, [esi]
  1328.         cmp     ch, 0xFF
  1329.         jnz     .nomarker2
  1330. .marker2:
  1331.         add     esi, 1
  1332.         sub     ebp, 1
  1333.         js      .eof
  1334.         cmp     byte [esi], 0xFF
  1335.         jz      .marker2
  1336.         cmp     byte [esi], 0
  1337.         jnz     .eof
  1338. .nomarker2:
  1339.         push    ecx
  1340.         shr     ch, cl
  1341.         add     esi, 1
  1342.         or      dl, ch
  1343.         pop     ecx
  1344.         push    edx
  1345.         shr     edx, 4
  1346. ; 8aaaa. (Second level in Huffman table) Does the current Huffman code fit in 12 bits?
  1347.         cmp     byte [ebx+edx*2], 4
  1348.         jbe     .l5
  1349.         jl      .eof
  1350. ; 9aaaaa. No; go to next level
  1351.         movzx   ebx, byte [ebx+edx*2+1]
  1352.         pop     edx
  1353.         shl     ebx, 5
  1354.         and     edx, 0xF
  1355.         lea     ebx, [eax+ebx+0x200]
  1356. ; 10aaaaa. Get current code length and value
  1357.         sub     cl, [ebx+edx*2]
  1358.         movzx   eax, byte [ebx+edx*2+1]
  1359.         neg     cl
  1360.         shl     ch, cl
  1361.         neg     cl
  1362.         add     cl, 8
  1363.         jmp     .done
  1364. .l5:
  1365. ; 9aaaab. Yes; get current code length and value
  1366.         sub     cl, [ebx+edx*2]
  1367.         movzx   eax, byte [ebx+edx*2+1]
  1368.         neg     cl
  1369.         pop     edx
  1370.         shl     ch, cl
  1371.         neg     cl
  1372.         add     cl, 8
  1373.         jmp     .done
  1374. .l4:
  1375. ; 7aaab. Yes; go to next level
  1376.         movzx   ebx, byte [ebx+edx*2+1]
  1377.         pop     edx
  1378.         shl     ebx, 5
  1379.         and     edx, 0xF
  1380.         lea     ebx, [eax+ebx+0x200]
  1381. ; 8aaab. (Third level in Huffman table) Have we got enough bits?
  1382.         cmp     [ebx+edx*2], cl
  1383.         jbe     .l6
  1384. ; 9aaaba. No; load next byte
  1385.         sub     ebp, 1
  1386.         js      .eof
  1387.         mov     ch, [esi]
  1388.         cmp     ch, 0xFF
  1389.         jnz     .nomarker3
  1390. .marker3:
  1391.         add     esi, 1
  1392.         sub     ebp, 1
  1393.         js      .eof
  1394.         cmp     byte [esi], 0xFF
  1395.         jz      .marker3
  1396.         cmp     byte [esi], 0
  1397.         jnz     .eof
  1398. .nomarker3:
  1399.         push    ecx
  1400.         shr     ch, cl
  1401.         add     esi, 1
  1402.         or      dl, ch
  1403.         pop     ecx
  1404. ; 10aaaba. Get current code length and value
  1405.         sub     cl, [ebx+edx*2]
  1406.         movzx   eax, byte [ebx+edx*2+1]
  1407.         neg     cl
  1408.         shl     ch, cl
  1409.         neg     cl
  1410.         add     cl, 8
  1411.         jmp     .done
  1412. .l3:
  1413. ; 6aab. Yes; get current code length and value
  1414.         pop     eax
  1415. .l6:
  1416. ; 9aaabb. Yes; get current code length and value
  1417.         sub     cl, [ebx+edx*2]
  1418.         movzx   eax, byte [ebx+edx*2+1]
  1419.         xor     cl, 7
  1420.         shl     ch, cl
  1421.         xor     cl, 7
  1422.         add     ch, ch
  1423.         jmp     .done
  1424. .l2:
  1425. ; 3ab. Yes; get current code length and value
  1426.         sub     cl, [eax+ebx*2]
  1427.         movzx   eax, byte [eax+ebx*2+1]
  1428.         neg     cl
  1429.         shl     ch, cl
  1430.         neg     cl
  1431.         add     cl, 8
  1432.         jmp     .done
  1433. .l1:
  1434. ; 3b. Yes; get current code length and value
  1435.         mov     dl, [eax+ebx*2]
  1436.         movzx   eax, byte [eax+ebx*2+1]
  1437.         xchg    cl, dl
  1438.         sub     dl, cl
  1439.         shl     ch, cl
  1440.         mov     cl, dl
  1441. .done:
  1442.         mov     ebx, eax
  1443. }
  1444. ; Decode DCT coefficients for one 8*8 block in progressive mode
  1445. ; from input stream, given by pointer esi and length ebp
  1446. ; N.B. Speed optimization has sense here.
  1447. align 16
  1448. decode_progressive_coeff:
  1449.         mov     ecx, [huffman_bits]
  1450.         cmp     [ScanStart], 0
  1451.         jnz     .ac
  1452. ; DC coefficient
  1453.         cmp     [ApproxPosHigh], 0
  1454.         jz      .dc_first
  1455. ; DC coefficient, subsequent passes
  1456.         xor     eax, eax
  1457.         get_bit
  1458.         adc     eax, eax
  1459.         mov     [huffman_bits], ecx
  1460.         mov     cl, [ApproxPosLow]
  1461.         shl     eax, cl
  1462.         or      [edi], ax
  1463.         ret
  1464. .dc_first:
  1465. ; DC coefficient, first pass
  1466.         mov     eax, [edx+16]
  1467.         push    edx
  1468.         get_huffman_code
  1469.         get_bits true
  1470.         add     eax, [edx+48]
  1471.         mov     [edx+48], ax
  1472.         mov     [huffman_bits], ecx
  1473.         mov     cl, [ApproxPosLow]
  1474.         shl     eax, cl
  1475.         mov     [edi], ax
  1476.         ret
  1477. .ac:
  1478. ; AC coefficients
  1479.         movzx   eax, [ScanStart]
  1480.         cmp     al, [ScanEnd]
  1481.         ja      .ret
  1482.         cmp     dword [edx+52], 0
  1483.         jnz     .was_eob
  1484. .acloop:
  1485.         push    edx
  1486.         push    eax
  1487.         mov     eax, [edx+20]
  1488.         get_huffman_code
  1489.         pop     eax
  1490.         test    ebx, 15
  1491.         jz      .band
  1492.         push    eax ebx
  1493.         and     ebx, 15
  1494.         get_bits false
  1495.         pop     ebx
  1496.         xchg    eax, [esp]
  1497.         shr     ebx, 4
  1498. .zeroloop1:
  1499.         push    eax ebx
  1500.         movzx   eax, byte [zigzag+eax]
  1501.         xor     ebx, ebx
  1502.         cmp     word [edi+eax], bx
  1503.         jz      .zeroloop2
  1504.         get_bit
  1505.         jnc     @f
  1506.         push    ecx
  1507.         mov     cl, [ApproxPosLow]
  1508.         xor     ebx, ebx
  1509.         cmp     byte [edi+eax+1], 80h
  1510.         adc     ebx, 0
  1511.         add     ebx, ebx
  1512.         sub     ebx, 1
  1513.         shl     ebx, cl
  1514.         pop     ecx
  1515.         add     [edi+eax], bx
  1516. @@:
  1517.         pop     ebx eax
  1518. @@:
  1519.         add     eax, 1
  1520.         cmp     al, [ScanEnd]
  1521.         ja      decode_data_unit.eof
  1522.         jmp     .zeroloop1
  1523. .zeroloop2:
  1524.         pop     ebx eax
  1525.         sub     ebx, 1
  1526.         jns     @b
  1527. .nozero1:
  1528.         pop     ebx
  1529.         test    ebx, ebx
  1530.         jz      @f
  1531.         push    eax
  1532.         movzx   eax, byte [zigzag+eax]
  1533.         push    ecx
  1534.         mov     cl, [ApproxPosLow]
  1535.         shl     ebx, cl
  1536.         pop     ecx
  1537.         mov     [edi+eax], bx
  1538.         pop     eax
  1539. @@:
  1540.         add     eax, 1
  1541.         pop     edx
  1542.         cmp     al, [ScanEnd]
  1543.         jbe     .acloop
  1544.         mov     [huffman_bits], ecx
  1545. .ret:
  1546.         ret
  1547. .eof:
  1548.         jmp     decode_data_unit.eof
  1549. .band:
  1550.         shr     ebx, 4
  1551.         cmp     ebx, 15
  1552.         jnz     .eob
  1553.         push    0
  1554.         jmp     .zeroloop1
  1555. .eob:
  1556.         pop     edx
  1557.         push    eax
  1558.         mov     eax, 1
  1559.         test    ebx, ebx
  1560.         jz      .eob0
  1561. @@:
  1562.         get_bit
  1563.         adc     eax, eax
  1564.         sub     ebx, 1
  1565.         jnz     @b
  1566. .eob0:
  1567.         mov     [edx+52], eax
  1568.         pop     eax
  1569. .was_eob:
  1570.         sub     dword [edx+52], 1
  1571.         cmp     al, [ScanEnd]
  1572.         ja      .ret2
  1573. .zeroloop3:
  1574.         push    eax
  1575.         movzx   eax, byte [zigzag+eax]
  1576.         xor     ebx, ebx
  1577.         cmp     word [edi+eax], bx
  1578.         jz      @f
  1579.         get_bit
  1580.         jnc     @f
  1581.         push    ecx
  1582.         mov     cl, [ApproxPosLow]
  1583.         xor     ebx, ebx
  1584.         cmp     byte [edi+eax+1], 80h
  1585.         adc     ebx, 0
  1586.         add     ebx, ebx
  1587.         sub     ebx, 1
  1588.         shl     ebx, cl
  1589.         pop     ecx
  1590.         add     [edi+eax], bx
  1591. @@:
  1592.         pop     eax
  1593.         add     eax, 1
  1594.         cmp     al, [ScanEnd]
  1595.         jbe     .zeroloop3
  1596. .ret2:
  1597.         mov     [huffman_bits], ecx
  1598.         ret
  1599.  
  1600. handle_progressive:
  1601.         cmp     [dct_buffer], 0
  1602.         jnz     @f
  1603.         ret
  1604. @@:
  1605. ; information for all components
  1606.         mov     esi, components
  1607.         xor     ebp, ebp
  1608.         movzx   ecx, byte [ebx+18]
  1609. .next_component:
  1610.         mov     edi, cur_components
  1611.         lodsb   ; ComponentID
  1612.         lodsd
  1613.         mov     ax, 0x0101
  1614.         stosd   ; db V, db H, db VFactor, db HFactor
  1615.         xor     eax, eax
  1616.         mov     al, byte [edi-1]        ; get HFactor
  1617.         mul     byte [ebx+18]           ; number of components
  1618.         stosd                   ; HIncrement_i = HFactor_i * sizeof(pixel)
  1619.         mov     al, byte [edi-4-2]      ; get VFactor
  1620.         mul     byte [ebx+18]           ; number of components
  1621.         mul     dword [ebx+4]           ; image width
  1622.         stosd                   ; VIncrement_i = VFactor_i * sizeof(row)
  1623.         lodsb
  1624.         and     eax, 3
  1625.         cmp     [quant_tables_defined+eax], 0
  1626.         jz      .error
  1627.         shl     eax, 8
  1628.         add     eax, quant_tables
  1629.         stosd           ; dd QuantizationTable
  1630.         stosd           ; dd DCTable - ignored
  1631.         mov     eax, ebp
  1632.         mul     [dct_buffer_size]
  1633.         add     eax, [dct_buffer]
  1634.         stosd           ; instead of dd ACTable - pointer to current DCT coefficients
  1635.         push    ecx
  1636.         mov     eax, [ebx+4]
  1637.         movzx   ecx, byte [edi-21]      ; get HFactor
  1638. ;       cdq     ; edx = 0 as a result of previous mul
  1639.         div     ecx
  1640.         stosd           ; dd width / HFactor_i
  1641.         stosd
  1642.         xchg    eax, ecx
  1643.         inc     eax
  1644.         sub     eax, edx
  1645.         stosd           ; dd HFactor_i+1 - (width % HFactor_i)
  1646.         mov     eax, [ebx+8]
  1647.         movzx   ecx, byte [edi-34]      ; get VFactor
  1648.         cdq
  1649.         div     ecx
  1650.         stosd           ; dd height / VFactor_i
  1651.         stosd
  1652.         xchg    eax, ecx
  1653.         inc     eax
  1654.         sub     eax, edx
  1655.         stosd           ; dd VFactor_i+1 - (height % VFactor_i)
  1656.         pop     ecx
  1657.         xor     eax, eax
  1658.         test    ebp, ebp
  1659.         setnp   al
  1660.         ror     eax, 1
  1661.         stosd           ; dd DCPrediction
  1662.         mov     eax, ebp
  1663.         stosd           ; dd ComponentOffset
  1664.         inc     ebp
  1665.         push    ecx
  1666.         mov     [cur_components_end], edi
  1667.         lea     edx, [edi-56]
  1668. ; do IDCT and unpack
  1669.         mov     edi, [ebx+28]
  1670.         add     edi, ebx
  1671.         mov     [cur_out_ptr], edi
  1672.         mov     [not_interleaved], 1
  1673.         call    init_limits
  1674. .decode_loop:
  1675.         call    decode_MCU
  1676.         sub     [cur_x], 1
  1677.         jnz     .decode_loop
  1678.         call    next_line
  1679.         sub     [cur_y], 1
  1680.         jnz     .decode_loop
  1681.         pop     ecx
  1682.         dec     ecx
  1683.         jnz     .next_component
  1684. ; image unpacked, return
  1685. .error:
  1686.         push    ebx
  1687.         push    68
  1688.         pop     eax
  1689.         push    13
  1690.         pop     ebx
  1691.         mov     ecx, [dct_buffer]
  1692.         int     0x40
  1693.         pop     ebx
  1694.         ret
  1695.  
  1696. ; Support for YCbCr -> RGB conversion
  1697. ; R = Y                          + 1.402 * (Cr - 128)
  1698. ; G = Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)
  1699. ; B = Y +   1.772 * (Cb - 128)
  1700. ; When converting YCbCr -> RGB, we need to do some multiplications;
  1701. ; to be faster, we precalculate the table for all 256 possible values
  1702. ; Also we approximate fractions with N/65536, this gives sufficient precision
  1703. initialize_color_table:
  1704. ; 1.402 = 1 + 26345/65536, -0.71414 = -46802/65536
  1705. ; -0.34414 = -22554/65536, 1.772 = 1 + 50594/65536
  1706.         mov     edi, color_table_1
  1707.         mov     ecx, 128
  1708. ; 1. Cb -> 1.772*Cb
  1709.         xor     eax, eax
  1710.         mov     dx, 8000h
  1711. .l1:
  1712.         push    ecx
  1713. @@:
  1714.         stosd
  1715.         add     dx, 50594
  1716.         adc     eax, 1
  1717.         loop    @b
  1718.         neg     dx
  1719.         adc     eax, -1
  1720.         neg     eax
  1721.         pop     ecx
  1722.         jnz     .l1
  1723. ; 2. Cb -> -0.34414*Cb
  1724.         mov     ax, dx
  1725. .l2:
  1726.         push    ecx
  1727. @@:
  1728.         stosd
  1729.         sub     eax, 22554
  1730.         loop    @b
  1731.         neg     eax
  1732.         pop     ecx
  1733.         cmp     ax, dx
  1734.         jnz     .l2
  1735.         xor     eax, eax
  1736. ; 3. Cr -> -0.71414*Cr
  1737. .l3:
  1738.         push    ecx
  1739. @@:
  1740.         stosd
  1741.         sub     eax, 46802
  1742.         loop    @b
  1743.         neg     eax
  1744.         pop     ecx
  1745.         jnz     .l3
  1746. ; 4. Cr -> 1.402*Cr
  1747. .l4:
  1748.         push    ecx
  1749. @@:
  1750.         stosd
  1751.         add     dx, 26345
  1752.         adc     eax, 1
  1753.         loop    @b
  1754.         neg     dx
  1755.         adc     eax, -1
  1756.         neg     eax
  1757.         pop     ecx
  1758.         jnz     .l4
  1759.         ret
  1760.  
  1761. ; this function is called in the end of image loading
  1762. convert_to_rgb:
  1763. ; some checks
  1764.         test    ebx, ebx        ; image exists?
  1765.         jz      .ret
  1766.         cmp     byte [ebx+18], 3        ; full-color image?
  1767.         jz      .ycc2rgb
  1768.         cmp     byte [ebx+18], 4
  1769.         jz      .ycck2rgb
  1770. .ret:
  1771.         ret
  1772. .ycc2rgb:
  1773. ; conversion is needed
  1774.         mov     esi, [ebx+4]
  1775.         imul    esi, [ebx+8]
  1776.         lea     edi, [ebx+44]
  1777.         push    ebx
  1778. ; N.B. Speed optimization has sense here.
  1779. align 16
  1780. .loop:
  1781. ;       mov     ebx, [edi]
  1782. ;       mov     edx, ebx
  1783. ;       mov     ecx, ebx
  1784. ;       movzx   ebx, bl         ; ebx = Y
  1785. ;       shr     edx, 16
  1786. ;       mov     eax, ebx
  1787. ;       movzx   edx, dl         ; edx = Cr
  1788. ;       movzx   ecx, ch         ; ecx = Cb
  1789.         movzx   ebx, byte [edi]
  1790.         movzx   ecx, byte [edi+1]
  1791.         mov     eax, ebx
  1792.         movzx   edx, byte [edi+2]
  1793. ; B = Y + color_table_1[Cb]
  1794.         add     eax, [color_table_1+ecx*4]
  1795.         mov     ebp, [color_table_2+ecx*4]
  1796.         cmp     eax, 80000000h
  1797.         sbb     ecx, ecx
  1798.         and     eax, ecx
  1799.         add     ebp, [color_table_3+edx*4]
  1800.         cmp     eax, 0x100
  1801.         sbb     ecx, ecx
  1802.         not     ecx
  1803.         sar     ebp, 16
  1804.         or      eax, ecx
  1805.         mov     [edi], al
  1806. ; G = Y + color_table_2[Cb] + color_table_3[Cr]
  1807.         lea     eax, [ebx+ebp]
  1808.         cmp     eax, 80000000h
  1809.         sbb     ecx, ecx
  1810.         and     eax, ecx
  1811.         cmp     eax, 0x100
  1812.         sbb     ecx, ecx
  1813.         not     ecx
  1814.         or      eax, ecx
  1815.         mov     [edi+1], al
  1816. ; R = Y + color_table_4[Cr]
  1817.         mov     eax, ebx
  1818.         add     eax, [color_table_4+edx*4]
  1819.         cmp     eax, 80000000h
  1820.         sbb     ecx, ecx
  1821.         and     eax, ecx
  1822.         cmp     eax, 0x100
  1823.         sbb     ecx, ecx
  1824.         not     ecx
  1825.         or      eax, ecx
  1826.         mov     [edi+2], al
  1827.         add     edi, 3
  1828.         sub     esi, 1
  1829.         jnz     .loop
  1830.         pop     ebx
  1831.         ret
  1832. .ycck2rgb:
  1833. ; conversion is needed
  1834.         mov     esi, [ebx+4]
  1835.         imul    esi, [ebx+8]
  1836.         push    ebx
  1837.         push    esi
  1838.         lea     edi, [ebx+44]
  1839.         mov     esi, edi
  1840. ; N.B. Speed optimization has sense here.
  1841. align 16
  1842. .kloop:
  1843. ;       mov     ebx, [esi]
  1844. ;       mov     edx, ebx
  1845. ;       mov     ecx, ebx
  1846. ;       movzx   ebx, bl         ; ebx = Y
  1847. ;       shr     edx, 16
  1848. ;       mov     eax, ebx
  1849. ;       movzx   edx, dl         ; edx = Cr
  1850. ;       movzx   ecx, ch         ; ecx = Cb
  1851.         movzx   ebx, byte [esi]
  1852.         movzx   ecx, byte [esi+1]
  1853.         mov     eax, ebx
  1854.         movzx   edx, byte [esi+2]
  1855. ; B = Y + color_table_1[Cb]
  1856.         add     eax, [color_table_1+ecx*4]
  1857.         mov     ebp, [color_table_2+ecx*4]
  1858.         cmp     eax, 80000000h
  1859.         sbb     ecx, ecx
  1860.         and     eax, ecx
  1861.         add     ebp, [color_table_3+edx*4]
  1862.         cmp     eax, 0x100
  1863.         sbb     ecx, ecx
  1864.         not     ecx
  1865.         sar     ebp, 16
  1866.         or      eax, ecx
  1867.         xor     al, 0xFF
  1868.         mul     byte [esi+3]
  1869.         add     al, ah
  1870.         adc     ah, 0
  1871.         add     al, 80h
  1872.         adc     ah, 0
  1873.         mov     byte [edi], ah
  1874. ; G = Y + color_table_2[Cb] + color_table_3[Cr]
  1875.         lea     eax, [ebx+ebp]
  1876.         cmp     eax, 80000000h
  1877.         sbb     ecx, ecx
  1878.         and     eax, ecx
  1879.         cmp     eax, 0x100
  1880.         sbb     ecx, ecx
  1881.         not     ecx
  1882.         or      eax, ecx
  1883.         xor     al, 0xFF
  1884.         mul     byte [esi+3]
  1885.         add     al, ah
  1886.         adc     ah, 0
  1887.         add     al, 80h
  1888.         adc     ah, 0
  1889.         mov     byte [edi+1], ah
  1890. ; R = Y + color_table_4[Cr]
  1891.         mov     eax, ebx
  1892.         add     eax, [color_table_4+edx*4]
  1893.         cmp     eax, 80000000h
  1894.         sbb     ecx, ecx
  1895.         and     eax, ecx
  1896.         cmp     eax, 0x100
  1897.         sbb     ecx, ecx
  1898.         not     ecx
  1899.         or      eax, ecx
  1900.         xor     al, 0xFF
  1901.         mul     byte [esi+3]
  1902.         add     al, ah
  1903.         adc     ah, 0
  1904.         add     al, 80h
  1905.         adc     ah, 0
  1906.         mov     byte [edi+2], ah
  1907.         add     esi, 4
  1908.         add     edi, 3
  1909.         sub     dword [esp], 1
  1910.         jnz     .kloop
  1911.         pop     eax
  1912.         pop     ebx
  1913. ; now correct values in RAW header
  1914.         mov     byte [ebx+12], 24
  1915.         mov     byte [ebx+18], 3
  1916.         mov     ecx, [ebx+32]
  1917.         shr     ecx, 2
  1918.         lea     ecx, [ecx*3]
  1919.         mov     [ebx+22], ecx
  1920. ; release some memory - must succeed because we decrease size
  1921.         add     ecx, 44+1
  1922.         mov     edx, ebx
  1923.         push    68
  1924.         pop     eax
  1925.         push    20
  1926.         pop     ebx
  1927.         int     0x40
  1928.         mov     ebx, eax
  1929.         ret
  1930.  
  1931. ; Decodes one data unit, that is, 8*8 block,
  1932. ; from input stream, given by pointer esi and length ebp
  1933. ; N.B. Speed optimization has sense here.
  1934. align 16
  1935. decode_data_unit:
  1936. ; edx -> component data
  1937.         cmp     [progressive], 0
  1938.         jz      @f
  1939.         mov     edi, [edx+20]
  1940.         add     dword [edx+20], 64*2
  1941.         jmp     .coeff_decoded
  1942. @@:
  1943.         mov     edi, dct_coeff
  1944.         mov     ecx, 64*2/4
  1945.         xor     eax, eax
  1946.         rep     stosd
  1947.         mov     edi, zigzag+1
  1948.         mov     ecx, [huffman_bits]
  1949. ; read DC coefficient
  1950.         mov     eax, [edx+16]
  1951.         push    edx
  1952.         get_huffman_code
  1953.         get_bits true
  1954.         add     eax, [edx+48]
  1955.         mov     [dct_coeff], ax
  1956.         mov     [edx+48], ax
  1957. ; read AC coefficients
  1958. @@:
  1959.         mov     eax, [edx+20]
  1960.         push    edx
  1961.         get_huffman_code
  1962.         shr     eax, 4
  1963.         and     ebx, 15
  1964.         jz      .band
  1965.         add     edi, eax
  1966.         cmp     edi, zigzag+64
  1967.         jae     .eof
  1968.         get_bits true
  1969.         movzx   ebx, byte [edi]
  1970.         mov     [dct_coeff+ebx], ax
  1971.         add     edi, 1
  1972.         cmp     edi, zigzag+64
  1973.         jb      @b
  1974.         jmp     .do_idct
  1975. .band:
  1976.         pop     edx
  1977.         cmp     al, 15
  1978.         jnz     .do_idct
  1979.         add     edi, 16
  1980.         cmp     edi, zigzag+64
  1981.         jb      @b
  1982. ;       jmp     .eof
  1983. .do_idct:
  1984.         mov     edi, dct_coeff
  1985.         mov     [huffman_bits], ecx
  1986. ; coefficients loaded, now IDCT
  1987. .coeff_decoded:
  1988.         mov     eax, [edx+12]
  1989.         mov     ebx, idct_tmp_area
  1990. .idct_loop1:
  1991.         mov     cx, word [edi+1*16]
  1992. repeat 6
  1993.         or      cx, word [edi+(%+1)*16]
  1994. end repeat
  1995.         jnz     .real_transform
  1996.         fild    word [edi]
  1997.         fmul    dword [eax]
  1998.         fstp    dword [ebx]
  1999.         mov     ecx, [ebx]
  2000. repeat 7
  2001.         mov     [ebx+%*32], ecx
  2002. end repeat
  2003.         jmp     .idct_next1
  2004. .real_transform:
  2005. ; S0,...,S7 - transformed values, s0,...,s7 - sought-for values
  2006. ; S0,...,S7 are dequantized;
  2007. ; dequantization table elements were multiplied to [idct_pre_table],
  2008. ; so S0,S1,... later denote S0/2\sqrt{2},S1*\cos{\pi/16}/2,...
  2009. ;       sqrt2 = \sqrt{2}, cos = 2\cos{\pi/8},
  2010. ;       cos_sum = -2(\cos{\pi/8}+\cos{3\pi/8}), cos_diff = 2(\cos{\pi/8}-\cos{3\pi/8})
  2011. ; Now formulas:
  2012. ; s0 = ((S0+S4)+(S2+S6)) + ((S1+S7)+(S3+S5))
  2013. ; s7 = ((S0+S4)+(S2+S6)) - ((S1+S7)+(S3+S5))
  2014. ; val0 = ((cos-1)S1-(cos+cos_sum+1)S3+(cos+cos_sum-1)S5-(cos+1)S7)
  2015. ; s1 = ((S0-S4)+((sqrt2-1)S2-(sqrt2+1)S6)) + val0
  2016. ; s6 = ((S0-S4)+((sqrt2-1)S2-(sqrt2+1)S6)) - val0
  2017. ; val1 = (S1+S7-S3-S5)sqrt2 - val0
  2018. ; s2 = ((S0-S4)-((sqrt2-1)S2-(sqrt2+1)S6)) + val1
  2019. ; s5 = ((S0-S4)-((sqrt2-1)S2-(sqrt2+1)S6)) - val1
  2020. ; val2 = (S1-S7)cos_diff - (S1-S3+S5-S7)cos + val1
  2021. ; s3 = ((S0+S4)-(S2+S6)) - val2
  2022. ; s4 = ((S0+S4)-(S2+S6)) + val2
  2023.         fild    word [edi+3*16]
  2024.         fmul    dword [eax+3*32]
  2025.         fild    word [edi+5*16]
  2026.         fmul    dword [eax+5*32]        ; st0=S5,st1=S3
  2027.         fadd    st1,st0
  2028.         fadd    st0,st0
  2029.         fsub    st0,st1         ; st0=S5-S3,st1=S5+S3
  2030.         fild    word [edi+1*16]
  2031.         fmul    dword [eax+1*32]
  2032.         fild    word [edi+7*16]
  2033.         fmul    dword [eax+7*32]        ; st0=S7,st1=S1
  2034.         fsub    st1,st0
  2035.         fadd    st0,st0
  2036.         fadd    st0,st1         ; st0=S1+S7,st1=S1-S7,st2=S5-S3,st3=S5+S3
  2037.         fadd    st3,st0
  2038.         fadd    st0,st0
  2039.         fsub    st0,st3         ; st0=S1-S3-S5+S7,st1=S1-S7,st2=S5-S3,st3=S1+S3+S5+S7
  2040.         fmul    [idct_sqrt2]
  2041.         fld     st2
  2042.         fadd    st0,st2
  2043.         fmul    [idct_cos]      ; st0=(S1-S3+S5-S7)cos,st1=(S1-S3-S5+S7)sqrt2,
  2044.                                 ; st2=S1-S7,st3=S5-S3,st4=S1+S3+S5+S7
  2045.         fxch    st2
  2046.         fmul    [idct_cos_diff]
  2047.         fsub    st0,st2         ; st0=(S1-S7)cos_diff - (S1-S3+S5-S7)cos
  2048.         fxch    st3
  2049.         fmul    [idct_cos_sum]
  2050.         fadd    st0,st2         ; st0=(S5-S3)cos_sum+(S1-S3+S5-S7)cos
  2051.         fsub    st0,st4         ; st0=val0
  2052.         fsub    st1,st0         ; st0=val0,st1=val1,st2=(S1-S3+S5-S7)cos,
  2053.                                 ; st3=(S1-S7)cos_diff-(S1-S3+S5-S7)cos,st4=S1+S3+S5+S7
  2054.         fxch    st2
  2055.         fstp    st0
  2056.         fadd    st2,st0         ; st0=val1,st1=val0,st2=val2,st3=S1+S3+S5+S7
  2057.  
  2058.         fild    word [edi+0*16]
  2059.         fmul    dword [eax+0*32]
  2060.         fild    word [edi+4*16]
  2061.         fmul    dword [eax+4*32]        ; st0=S4,st1=S0
  2062.         fsub    st1,st0
  2063.         fadd    st0,st0
  2064.         fadd    st0,st1         ; st0=S0+S4,st1=S0-S4
  2065.         fild    word [edi+6*16]
  2066.         fmul    dword [eax+6*32]
  2067.         fild    word [edi+2*16]
  2068.         fmul    dword [eax+2*32]        ; st0=S2,st1=S6
  2069.         fadd    st1,st0
  2070.         fadd    st0,st0
  2071.         fsub    st0,st1         ; st0=S2-S6,st1=S2+S6
  2072.         fmul    [idct_sqrt2]
  2073.         fsub    st0,st1
  2074.         fsub    st3,st0
  2075.         fadd    st0,st0
  2076.         fadd    st0,st3         ; st0=(S0-S4)+((S2-S6)sqrt2-(S2+S6))
  2077.                                 ; st3=(S0-S4)-((S2-S6)sqrt2-(S2+S6))
  2078.         fxch    st1
  2079.         fsub    st2,st0
  2080.         fadd    st0,st0
  2081.         fadd    st0,st2         ; st0=(S0+S4)+(S2+S6),st1=(S0-S4)+((S2-S6)sqrt2-(S2+S6)),
  2082.                                 ; st2=(S0+S4)-(S2+S6),st3=(S0-S4)-((S2-S6)sqrt2-(S2+S6))
  2083.                                 ; st4=val1,st5=val0,st6=val2,st7=S1+S3+S5+S7
  2084.         fsubr   st7,st0
  2085.         fadd    st0,st0
  2086.         fsub    st0,st7
  2087.         fstp    dword [ebx+0*32]
  2088.         fsubr   st4,st0
  2089.         fadd    st0,st0
  2090.         fsub    st0,st4
  2091.         fstp    dword [ebx+1*32]
  2092.         fadd    st4,st0
  2093.         fadd    st0,st0
  2094.         fsub    st0,st4
  2095.         fstp    dword [ebx+3*32]
  2096.         fsubr   st1,st0
  2097.         fadd    st0,st0
  2098.         fsub    st0,st1
  2099.         fstp    dword [ebx+2*32]
  2100.         fstp    dword [ebx+5*32]
  2101.         fstp    dword [ebx+6*32]
  2102.         fstp    dword [ebx+4*32]
  2103.         fstp    dword [ebx+7*32]
  2104. .idct_next1:
  2105.         add     ebx, 4
  2106.         add     edi, 2
  2107.         add     eax, 4
  2108.         cmp     ebx, idct_tmp_area+8*4
  2109.         jb      .idct_loop1
  2110.         sub     ebx, 8*4
  2111. .idct_loop2:
  2112.         fld     dword [ebx+3*4]
  2113.         fld     dword [ebx+5*4]
  2114.         fadd    st1,st0
  2115.         fadd    st0,st0
  2116.         fsub    st0,st1         ; st0=S5-S3,st1=S5+S3
  2117.         fld     dword [ebx+1*4]
  2118.         fld     dword [ebx+7*4]
  2119.         fsub    st1,st0
  2120.         fadd    st0,st0
  2121.         fadd    st0,st1         ; st0=S1+S7,st1=S1-S7,st2=S5-S3,st3=S5+S3
  2122.         fadd    st3,st0
  2123.         fadd    st0,st0
  2124.         fsub    st0,st3         ; st0=S1-S3-S5+S7,st1=S1-S7,st2=S5-S3,st3=S1+S3+S5+S7
  2125.         fmul    [idct_sqrt2]
  2126.         fld     st2
  2127.         fadd    st0,st2
  2128.         fmul    [idct_cos]      ; st0=(S1-S3+S5-S7)cos,st1=(S1-S3-S5+S7)sqrt2,
  2129.                                 ; st2=S1-S7,st3=S5-S3,st4=S1+S3+S5+S7
  2130.         fxch    st2
  2131.         fmul    [idct_cos_diff]
  2132.         fsub    st0,st2         ; st0=(S1-S7)cos_diff - (S1-S3+S5-S7)cos
  2133.         fxch    st3
  2134.         fmul    [idct_cos_sum]
  2135.         fadd    st0,st2         ; st0=(S5-S3)cos_sum+(S1-S3+S5-S7)cos
  2136.         fsub    st0,st4         ; st0=val0
  2137.         fsub    st1,st0         ; st0=val0,st1=val1,st2=(S1-S3+S5-S7)cos,
  2138.                                 ; st3=(S1-S7)cos_diff-(S1-S3+S5-S7)cos,st4=S1+S3+S5+S7
  2139.         fxch    st2
  2140.         fstp    st0
  2141.         fadd    st2,st0         ; st0=val1,st1=val0,st2=val2,st3=S1+S3+S5+S7
  2142.  
  2143.         fld     dword [ebx+0*4]
  2144.         fld     dword [ebx+4*4]
  2145.         fsub    st1,st0
  2146.         fadd    st0,st0
  2147.         fadd    st0,st1         ; st0=S0+S4,st1=S0-S4
  2148.         fld     dword [ebx+6*4]
  2149.         fld     dword [ebx+2*4]
  2150.         fadd    st1,st0
  2151.         fadd    st0,st0
  2152.         fsub    st0,st1         ; st0=S2-S6,st1=S2+S6
  2153.         fmul    [idct_sqrt2]
  2154.         fsub    st0,st1
  2155.         fsub    st3,st0
  2156.         fadd    st0,st0
  2157.         fadd    st0,st3         ; st0=(S0-S4)+((S2-S6)sqrt2-(S2+S6))
  2158.                                 ; st3=(S0-S4)-((S2-S6)sqrt2-(S2+S6))
  2159.         fxch    st1
  2160.         fsub    st2,st0
  2161.         fadd    st0,st0
  2162.         fadd    st0,st2         ; st0=(S0+S4)+(S2+S6),st1=(S0-S4)+((S2-S6)sqrt2-(S2+S6)),
  2163.                                 ; st2=(S0+S4)-(S2+S6),st3=(S0-S4)-((S2-S6)sqrt2-(S2+S6))
  2164.                                 ; st4=val1,st5=val0,st6=val2,st7=S1+S3+S5+S7
  2165.         fsubr   st7,st0
  2166.         fadd    st0,st0
  2167.         fsub    st0,st7
  2168.         fistp   dword [ebx+0*4]
  2169.         fsubr   st4,st0
  2170.         fadd    st0,st0
  2171.         fsub    st0,st4
  2172.         fistp   dword [ebx+1*4]
  2173.         fadd    st4,st0
  2174.         fadd    st0,st0
  2175.         fsub    st0,st4
  2176.         fistp   dword [ebx+3*4]
  2177.         fsubr   st1,st0
  2178.         fadd    st0,st0
  2179.         fsub    st0,st1
  2180.         fistp   dword [ebx+2*4]
  2181.         fistp   dword [ebx+5*4]
  2182.         fistp   dword [ebx+6*4]
  2183.         fistp   dword [ebx+4*4]
  2184.         fistp   dword [ebx+7*4]
  2185.  
  2186.         add     ebx, 32
  2187.         cmp     ebx, idct_tmp_area+32*8
  2188.         jb      .idct_loop2
  2189.  
  2190.         mov     ecx, idct_tmp_area
  2191.         mov     edi, decoded_data - 1
  2192. .idct_loop3:
  2193.         mov     eax, [ecx]
  2194.         add     ecx, 4
  2195.         add     eax, 80h
  2196.         cmp     eax, 80000000h
  2197.         sbb     ebx, ebx
  2198.         add     edi, 1
  2199.         and     eax, ebx
  2200.         cmp     eax, 100h
  2201.         sbb     ebx, ebx
  2202.         not     ebx
  2203.         or      eax, ebx
  2204.         sub     al, [edx+51]
  2205.         cmp     ecx, idct_tmp_area+64*4
  2206.         mov     [edi], al
  2207.         jb      .idct_loop3
  2208. ; done
  2209.         mov     ebx, [_ebx]
  2210.         ret
  2211.  
  2212. .eof:
  2213. ; EOF or incorrect data during scanning
  2214.         mov     esp, [_esp]
  2215.         mov     ebx, [_ebx]
  2216.         jmp     START.end
  2217. ;---------------------------------------------------------------------
  2218. check_header:
  2219.         pushad
  2220.         mov     eax,dword [esp+36]
  2221.         push    eax
  2222.         and     dword [eax+8], 0
  2223.         mov     esi, [eax]
  2224.         mov     ebp, [eax+12]
  2225.         call    get_marker
  2226.         jc      .err
  2227.         cmp     al, 0xD8
  2228.         jnz     .err
  2229.         pop     eax
  2230.         popad
  2231.         ret     4
  2232. .err:
  2233.         pop     eax
  2234.         inc     dword [eax+8]
  2235.         popad  
  2236.         ret     4
  2237. ;---------------------------------------------------------------------
  2238. zigzag:
  2239. ; (x,y) -> 2*(x+y*8)
  2240. repeat 8
  2241.         .cur = %
  2242.         if .cur and 1
  2243.                 repeat %
  2244.                         db      2*((%-1) + (.cur-%)*8)
  2245.                 end repeat
  2246.         else
  2247.                 repeat %
  2248.                         db      2*((.cur-%) + (%-1)*8)
  2249.                 end repeat
  2250.         end if
  2251. end repeat
  2252. repeat 7
  2253.         .cur = %
  2254.         if .cur and 1
  2255.                 repeat 8-%
  2256.                         db      2*((%+.cur-1) + (8-%)*8)
  2257.                 end repeat
  2258.         else
  2259.                 repeat 8-%
  2260.                         db      2*((8-%) + (%+.cur-1)*8)
  2261.                 end repeat
  2262.         end if
  2263. end repeat
  2264.  
  2265. align 4
  2266. idct_pre_table:
  2267. ; c_0 = 1/(2\sqrt{2}), c_i = cos(i*\pi/16)/2
  2268.         dd      0.35355339, 0.49039264, 0.461939766, 0.41573481
  2269.         dd      0.35355339, 0.27778512, 0.19134172, 0.09754516
  2270. idct_sqrt2      dd      1.41421356      ; \sqrt{2}
  2271. idct_cos        dd      1.847759065     ; 2\cos{\pi/8}
  2272. idct_cos_sum    dd      -2.61312593     ; -2(\cos{\pi/8} + \cos{3\pi/8})
  2273. idct_cos_diff   dd      1.08239220      ; 2(\cos{\pi/8} - \cos{3\pi/8})
  2274. ;---------------------------------------------------------------------
  2275. Associations:
  2276. dd  Associations.end - Associations
  2277. db 'JPEG',0
  2278. db 'JPG',0
  2279. db 'JPE',0
  2280. .end:
  2281. db 0
  2282. ;---------------------------------------------------------------------
  2283. align 4
  2284. EXPORTS:
  2285.         dd      szStart,        START
  2286.         dd      szVersion,      0x00010002
  2287.         dd      szCheck,        check_header
  2288.         dd      szAssoc,        Associations
  2289.         dd      0
  2290.  
  2291. szStart         db 'START',0
  2292. szVersion       db 'version',0
  2293. szCheck         db 'Check_Header',0
  2294. szAssoc         db 'Associations',0
  2295.  
  2296. section '.data' data readable writable align 16
  2297.  
  2298. ; up to 4 quantization tables
  2299. quant_tables            rd      4*64
  2300. quant_tables_defined    rb      4
  2301.  
  2302. ; Huffman tables
  2303. dc_huffman_defined      rb      4
  2304. ac_huffman_defined      rb      4
  2305. ; up to 4 DC Huffman tables
  2306. ;dc_huffman             rd      4*256*2
  2307. ; up to 4 AC Huffman tables
  2308. ;ac_huffman             rd      4*256*2
  2309. max_hufftable_size = (256 + (9+128)*16)*2
  2310. dc_huffman              rb      4*max_hufftable_size
  2311. ac_huffman              rb      4*max_hufftable_size
  2312.  
  2313. ; restart interval
  2314. restart_interval        dd      ?
  2315. decoded_MCUs            dd      ?
  2316.  
  2317. ; base esp,ebx values
  2318. _esp                    dd      ?
  2319. _ebx                    dd      ?
  2320.  
  2321. ; components information, up to 4 components
  2322. ; db ComponentIdentifier, db V, db H, db VFactor, db HFactor, db QuantizationTable
  2323. components              rb      4*6
  2324. max_v                   db      ?
  2325. max_h                   db      ?
  2326. cur_rst_marker          db      ?
  2327.                         db      ?
  2328. huffman_bits            dd      ?
  2329. block_width     dd      ?
  2330. block_height    dd      ?
  2331. block_delta_x   dd      ?
  2332. block_delta_y   dd      ?
  2333. cur_block_dx    dd      ?
  2334. cur_block_dy    dd      ?
  2335. x_num_blocks    dd      ?
  2336. y_num_blocks    dd      ?
  2337. delta_x         dd      ?
  2338. delta_y         dd      ?
  2339. pixel_size      dd      ?
  2340. line_size       dd      ?
  2341. cur_x           dd      ?
  2342. cur_y           dd      ?
  2343. max_x           dd      ?
  2344. max_y           dd      ?
  2345. cur_out_ptr     dd      ?
  2346. dct_buffer      dd      ?
  2347. dct_buffer_size dd      ?
  2348. ;ns                     dd      ?
  2349. ; +0: db V, db H, db VFactor, db HFactor, dd HIncrement, dd VIncrement,
  2350. ; +12: dd QuantizationTable, dd DCTable, dd ACTable,
  2351. ; +24: dd width/HFactor, dd width/HFactor-8k, dd HFactor+1-(width%HFactor),
  2352. ; +36: dd height/VFactor, dd height/VFactor-8m, dd VFactor+1-(height%VFactor),
  2353. ; +48: dw DCPrediction, db ?, db (0 for Y, 80h for Cb,Cr), dd ComponentOffset
  2354. cur_components          rb      4*56
  2355. cur_components_end      dd      ?
  2356. ; progressive JPEG?
  2357. progressive             db      ?
  2358. ; one component in the scan?
  2359. not_interleaved         db      ?
  2360. ; Adobe YCCK file?
  2361. adobe_ycck              db      ?
  2362.                         rb      1
  2363. ; parameters for progressive scan
  2364. ScanStart               db      ?
  2365. ScanEnd                 db      ?
  2366. ApproxPosLow            db      ?
  2367. ApproxPosHigh           db      ?
  2368. ; Fourier coefficients
  2369. dct_coeff               rw      64
  2370. ; Temporary space for IDCT
  2371. idct_tmp_area           rd      64
  2372. ; decoded block 8*8
  2373. decoded_data            rb      8*8
  2374. ; data for YCbCr -> RGB translation
  2375. color_table_1           rd      256
  2376. color_table_2           rd      256
  2377. color_table_3           rd      256
  2378. color_table_4           rd      256
  2379.