; +-------------------------------------------------------------------------+
;      This file is generated by The Interactive Disassembler (IDA)        
;      Copyright (c) 2005 by DataRescue sa/nv, <ida@datarescue.com>        
;             Licensed to: Sebastian Porst, 1 user std, 05/2005            
; +-------------------------------------------------------------------------+
.text:100607D0 ;  S U B R O U T I N E 
.text:100607D0 GetVbrTag       proc near               ; CODE XREF: sub_10059240+77p
.text:100607D0 pTagData        = dword ptr  4
.text:100607D0 buf             = dword ptr  8
.text:100607D0                 mov     ecx, [esp+buf]
.text:100607D4                 push    ebx
.text:100607D5                 push    ebp
.text:100607D6                 push    esi
.text:100607D7                 xor     eax, eax
.text:100607D9                 push    edi
.text:100607DA                 mov     edi, [esp+10h+pTagData]
.text:100607DE                 mov     dword ptr [edi+8], 0 ; pTagData->flags = 0;
.text:100607E5                 mov     dl, [ecx+1]     ; buf[1]
.text:100607E8 The local variable "int hmode" is not put on the stack but kept in ebx
.text:100607E8                 movzx   ebx, byte ptr [ecx+3]
.text:100607EC                 mov     al, dl
.text:100607EE                 and     dl, 0F0h        ; Some preparation for the first if
.text:100607F1                 shr     ebx, 6
.text:100607F4                 shr     eax, 3
.text:100607F7                 and     eax, 1
.text:100607FA                 mov     ebp, eax
.text:100607FC                 movzx   eax, byte ptr [ecx+2]
.text:10060800                 mov     esi, eax
.text:10060802                 mov     [esp+10h+pTagData], ebp ; h_id = (buf[1] >> 3) & 1;
.text:10060806                 shr     eax, 4
.text:10060809                 shl     ebp, 4
.text:1006080C                 add     eax, ebp
.text:1006080E                 mov     eax, ds:bitrate_table[eax*4]
.text:10060815                 mov     ebp, [esp+10h+pTagData]
.text:10060819 The local variable "int h_sr_index" is not put on the stack but kept in esi
.text:10060819                 shr     esi, 2
.text:1006081C                 and     esi, 3          ; h_sr_index = (buf[2] >> 2) & 3;
.text:1006081F                 cmp     dl, 0E0h        ; if ((buf[1]>>4)==0xE)
.text:10060822                 mov     [esp+10h+buf], eax
.text:10060826                 jnz     short loc_10060831
.text:10060828                 mov     edx, ds:samplerate_table2[esi*4] ; pTagData->samprate = samplerate_table[2][h_sr_index];
.text:1006082F                 jmp     short loc_1006083B
.text:10060831 ; ---------------------------------------------------------------------------
.text:10060831 loc_10060831:                           ; CODE XREF: GetVbrTag+56j
.text:10060831                 lea     eax, [esi+ebp*4]
.text:10060834                 mov     edx, ds:samplerate_table[eax*4] ; pTagData->samprate = samplerate_table[h_id][h_sr_index];
.text:1006083B loc_1006083B:                           ; CODE XREF: GetVbrTag+5Fj
.text:1006083B                 test    ebp, ebp        ; if( h_id )
.text:1006083D                 mov     [edi+4], edx
.text:10060840                 jz      short loc_1006084C
.text:10060842                 cmp     ebx, 3          ; if( h_mode != 3 )
.text:10060845                 jz      short loc_10060851
.text:10060847                 add     ecx, 36         ; buf+=(32+4);
.text:1006084A                 jmp     short loc_10060859
.text:1006084C ; ---------------------------------------------------------------------------
.text:1006084C loc_1006084C:                           ; CODE XREF: GetVbrTag+70j
.text:1006084C                 cmp     ebx, 3
.text:1006084F                 jz      short loc_10060856
.text:10060851 There's some heavy compiler optimization here. The +21 part which
.text:10060851 can be found in both if-clauses is reduced to one.
.text:10060851 loc_10060851:                           ; CODE XREF: GetVbrTag+75j
.text:10060851                 add     ecx, 21         ; buf+=(17+4);
.text:10060854                 jmp     short loc_10060859
.text:10060856 ; ---------------------------------------------------------------------------
.text:10060856 loc_10060856:                           ; CODE XREF: GetVbrTag+7Fj
.text:10060856                 add     ecx, 13         ; buf+=(9+4);
.text:10060859 More compiler optimization here. VBRTag is the string literal 'Xing'
.text:10060859 VBRTag2 is the string literal 'Info'.
.text:10060859 loc_10060859:                           ; CODE XREF: GetVbrTag+7Aj
.text:10060859                                         ; GetVbrTag+84j
.text:10060859                 mov     al, [ecx]
.text:1006085B Here come the if-clauses
.text:1006085B                 cmp     al, 'X'
.text:1006085D                 jz      short loc_10060863 ; buf[0] != VBRTag[0]
.text:1006085F                 cmp     al, 'I'
.text:10060861                 jnz     short return0   ; buf[0] != VBRTag2[0]
.text:10060863 loc_10060863:                           ; CODE XREF: GetVbrTag+8Dj
.text:10060863                 mov     al, [ecx+1]
.text:10060866                 cmp     al, 'i'
.text:10060868                 jz      short loc_1006086E ; buf[1] != VBRTag[1]
.text:1006086A                 cmp     al, 'n'
.text:1006086C                 jnz     short return0   ; buf[1] != VBRTag2[1]
.text:1006086E loc_1006086E:                           ; CODE XREF: GetVbrTag+98j
.text:1006086E                 mov     al, [ecx+2]
.text:10060871                 cmp     al, 'n'         ; buf[2] != VBRTag[2]
.text:10060873                 jz      short loc_10060879
.text:10060875                 cmp     al, 'f'         ; buf[2] != VBRTag2[2]
.text:10060877                 jnz     short return0
.text:10060879 loc_10060879:                           ; CODE XREF: GetVbrTag+A3j
.text:10060879                 mov     al, [ecx+3]
.text:1006087C                 cmp     al, 'g'         ; buf[3] != VBRTag[3]
.text:1006087E                 jz      short loc_1006088B
.text:10060880                 cmp     al, 'o'         ; buf[3] != VBRTag2[3]
.text:10060882                 jz      short loc_1006088B
.text:10060884 return0:                                ; CODE XREF: GetVbrTag+91j
.text:10060884                                         ; GetVbrTag+9Cj ...
.text:10060884                 pop     edi
.text:10060885                 pop     esi
.text:10060886                 pop     ebp
.text:10060887                 xor     eax, eax
.text:10060889                 pop     ebx
.text:1006088A                 retn
.text:1006088B ; ---------------------------------------------------------------------------
.text:1006088B loc_1006088B:                           ; CODE XREF: GetVbrTag+AEj
.text:1006088B                                         ; GetVbrTag+B2j
.text:1006088B                 xor     edx, edx
.text:1006088D                 add     ecx, 4          ; buf+=4;
.text:10060890 More compiler optimization: The function ExtractI4 has been inlined.
.text:10060890                 mov     [edi], ebp
.text:10060892                 mov     dh, [ecx]
.text:10060894                 movzx   eax, byte ptr [ecx+2]
.text:10060898                 add     ecx, 4
.text:1006089B                 mov     dl, [ecx-3]
.text:1006089E                 shl     edx, 8
.text:100608A1                 or      edx, eax
.text:100608A3                 movzx   eax, byte ptr [ecx-1]
.text:100608A7                 shl     edx, 8
.text:100608AA                 or      edx, eax
.text:100608AC                 test    dl, 1           ; if( head_flags & FRAMES_FLAG )
.text:100608AF                 mov     [edi+8], edx    ; pTagData->flags = ExtractI4(buf)
.text:100608B2 The local variable "head_flags" is kept in edx. It's not put
.text:100608B2 on the stack.
.text:100608B2                 jz      short loc_100608D3
.text:100608B4 Here comes the inlined ExtractI4 again
.text:100608B4                 movzx   esi, byte ptr [ecx+2]
.text:100608B8                 xor     eax, eax
.text:100608BA                 mov     ah, [ecx]
.text:100608BC                 mov     al, [ecx+1]
.text:100608BF                 shl     eax, 8
.text:100608C2                 or      eax, esi
.text:100608C4                 movzx   esi, byte ptr [ecx+3]
.text:100608C8                 shl     eax, 8
.text:100608CB                 or      eax, esi
.text:100608CD                 mov     [edi+0Ch], eax  ; pTagData->frames   = ExtractI4(buf)
.text:100608D0                 add     ecx, 4          ; buf+=4
.text:100608D3 loc_100608D3:                           ; CODE XREF: GetVbrTag+E2j
.text:100608D3                 test    dl, 2           ; if( head_flags & BYTES_FLAG )
.text:100608D6                 jz      short loc_100608F7
.text:100608D8 And more inlined ExtractI4
.text:100608D8                 movzx   esi, byte ptr [ecx+2]
.text:100608DC                 xor     eax, eax
.text:100608DE                 mov     ah, [ecx]
.text:100608E0                 mov     al, [ecx+1]
.text:100608E3                 shl     eax, 8
.text:100608E6                 or      eax, esi
.text:100608E8                 movzx   esi, byte ptr [ecx+3]
.text:100608EC                 shl     eax, 8
.text:100608EF                 or      eax, esi
.text:100608F1                 mov     [edi+10h], eax  ; pTagData->bytes
.text:100608F4                 add     ecx, 4          ; buf+=4;
.text:100608F7 loc_100608F7:                           ; CODE XREF: GetVbrTag+106j
.text:100608F7                 test    dl, 4           ; if( head_flags & TOC_FLAG )
.text:100608FA                 jz      short loc_10060914
.text:100608FC                 lea     esi, [edi+18h]
.text:100608FF                 test    esi, esi        ; if( pTagData->toc != NULL )
.text:10060901                 jz      short loc_10060911
.text:10060903                 xor     eax, eax
.text:10060905 Here comes the for-loop
.text:10060905 for(i=0;i<NUMTOCENTRIES;i++)
.text:10060905 loc_10060905:                           ; CODE XREF: GetVbrTag+13Fj
.text:10060905                 mov     bl, [eax+ecx]
.text:10060908                 mov     [esi+eax], bl   ; pTagData->toc[i] = buf[i];
.text:1006090B                 inc     eax
.text:1006090C                 cmp     eax, 64h
.text:1006090F                 jl      short loc_10060905
.text:10060911 loc_10060911:                           ; CODE XREF: GetVbrTag+131j
.text:10060911                 add     ecx, 64h        ; buf+=NUMTOCENTRIES;
.text:10060914 loc_10060914:                           ; CODE XREF: GetVbrTag+12Aj
.text:10060914                 test    dl, 8           ; if( head_flags & VBR_SCALE_FLAG )
.text:10060917                 mov     dword ptr [edi+14h], 0FFFFFFFFh ; pTagData->vbr_scale = -1;
.text:1006091E                 jz      short loc_1006093F
.text:10060920 More inlined ExtractI4
.text:10060920                 movzx   eax, byte ptr [ecx+2]
.text:10060924                 xor     edx, edx
.text:10060926                 mov     dh, [ecx]
.text:10060928                 mov     dl, [ecx+1]
.text:1006092B                 shl     edx, 8
.text:1006092E                 or      edx, eax
.text:10060930                 movzx   eax, byte ptr [ecx+3]
.text:10060934                 shl     edx, 8
.text:10060937                 or      edx, eax
.text:10060939                 mov     [edi+14h], edx  ; pTagData->vbr_scale = ExtractI4(buf);
.text:1006093C                 add     ecx, 4          ; buf+=4;
.text:1006093F Here comes the calculation ((h_id+1)*72000*h_bitrate) / pTagData->samprate;
.text:1006093F loc_1006093F:                           ; CODE XREF: GetVbrTag+14Ej
.text:1006093F                 lea     eax, [ebp+1]
.text:10060942                 imul    eax, [esp+10h+buf]
.text:10060947                 imul    eax, 72000
.text:1006094D                 cdq
.text:1006094E                 idiv    dword ptr [edi+4]
.text:10060951                 add     ecx, 15h        ; buf+=21;
.text:10060954                 mov     [edi+7Ch], eax  ; pTagData->headersize = calculation result
.text:10060957 The following lines are
.text:10060957 enc_delay = buf[0] << 4;
.text:10060957 enc_delay += buf[1] >> 4;
.text:10060957 enc_padding= (buf[1] & 0x0F)<<8;
.text:10060957 enc_padding += buf[2];
.text:10060957                 movzx   eax, byte ptr [ecx+1]
.text:1006095B                 movzx   esi, byte ptr [ecx]
.text:1006095E                 movzx   ecx, byte ptr [ecx+2]
.text:10060962                 mov     edx, eax
.text:10060964                 and     eax, 0Fh
.text:10060967                 shr     edx, 4
.text:1006096A                 shl     esi, 4
.text:1006096D                 shl     eax, 8
.text:10060970                 add     edx, esi
.text:10060972                 add     eax, ecx
.text:10060974                 test    edx, edx
.text:10060976                 jl      short loc_10060980 ; if (enc_delay<0
.text:10060978                 cmp     edx, 3000       ; || enc_delay > 3000)
.text:1006097E                 jle     short loc_10060983
.text:10060980 loc_10060980:                           ; CODE XREF: GetVbrTag+1A6j
.text:10060980                 or      edx, 0FFFFFFFFh ; enc_delay=-1;
.text:10060983 loc_10060983:                           ; CODE XREF: GetVbrTag+1AEj
.text:10060983                 test    eax, eax
.text:10060985                 jl      short loc_1006098E ; if (enc_padding<0
.text:10060987                 cmp     eax, 3000       ; || enc_padding > 3000)
.text:1006098C                 jle     short loc_10060991
.text:1006098E loc_1006098E:                           ; CODE XREF: GetVbrTag+1B5j
.text:1006098E                 or      eax, 0FFFFFFFFh ; enc_padding=-1;
.text:10060991 loc_10060991:                           ; CODE XREF: GetVbrTag+1BCj
.text:10060991                 mov     [edi+84h], eax  ; pTagData->enc_padding=enc_padding;
.text:10060997                 mov     [edi+80h], edx  ; pTagData->enc_delay=enc_delay;
.text:1006099D                 pop     edi
.text:1006099E                 pop     esi
.text:1006099F                 pop     ebp
.text:100609A0                 mov     eax, 1          ; return 1;
.text:100609A5                 pop     ebx
.text:100609A6                 retn
.text:100609A6 GetVbrTag       endp
.text:100609A6 ; ---------------------------------------------------------------------------