예제 #1
0
static void  BuildHuffmanTree( HUFF_ENTRY **HuffRoot,
                        ogg_uint32_t *HuffCodeArray,
                        unsigned char *HuffCodeLengthArray,
                        ogg_uint32_t HIndex,
                        const ogg_uint32_t *FreqList ){

  HUFF_ENTRY *entry_ptr;
  HUFF_ENTRY *search_ptr;

  /* First create a sorted linked list representing the frequencies of
     each token. */
  CreateHuffmanList( HuffRoot, HIndex, FreqList );

  /* Now build the tree from the list. */

  /* While there are at least two items left in the list. */
  while ( HuffRoot[HIndex]->Next != NULL ){
    /* Create the new node as the parent of the first two in the list. */
    entry_ptr = (HUFF_ENTRY *)_ogg_calloc(1,sizeof(*entry_ptr));
    entry_ptr->Value = -1;
    entry_ptr->Frequency = HuffRoot[HIndex]->Frequency +
      HuffRoot[HIndex]->Next->Frequency ;
    entry_ptr->ZeroChild = HuffRoot[HIndex];
    entry_ptr->OneChild = HuffRoot[HIndex]->Next;

    /* If there are still more items in the list then insert the new
       node into the list. */
    if (entry_ptr->OneChild->Next != NULL ){
      /* Set up the provisional 'new root' */
      HuffRoot[HIndex] = entry_ptr->OneChild->Next;
      HuffRoot[HIndex]->Previous = NULL;

      /* Now scan through the remaining list to insert the new entry
         at the appropriate point. */
      if ( entry_ptr->Frequency <= HuffRoot[HIndex]->Frequency ){
        entry_ptr->Next = HuffRoot[HIndex];
        HuffRoot[HIndex]->Previous = entry_ptr;
        entry_ptr->Previous = NULL;
        HuffRoot[HIndex] = entry_ptr;
      }else{
        search_ptr = HuffRoot[HIndex];
        while ( (search_ptr->Next != NULL) &&
                (search_ptr->Frequency < entry_ptr->Frequency) ){
          search_ptr = search_ptr->Next;
        }

        if ( search_ptr->Frequency < entry_ptr->Frequency ){
          entry_ptr->Next = NULL;
          entry_ptr->Previous = search_ptr;
          search_ptr->Next = entry_ptr;
        }else{
          entry_ptr->Next = search_ptr;
          entry_ptr->Previous = search_ptr->Previous;
          search_ptr->Previous->Next = entry_ptr;
          search_ptr->Previous = entry_ptr;
        }
      }
    }else{
      /* Build has finished. */
      entry_ptr->Next = NULL;
      entry_ptr->Previous = NULL;
      HuffRoot[HIndex] = entry_ptr;
    }

    /* Delete the Next/Previous properties of the children (PROB NOT NEC). */
    entry_ptr->ZeroChild->Next = NULL;
    entry_ptr->ZeroChild->Previous = NULL;
    entry_ptr->OneChild->Next = NULL;
    entry_ptr->OneChild->Previous = NULL;

  }

  /* Now build a code array from the tree. */
  CreateCodeArray( HuffRoot[HIndex], HuffCodeArray,
                   HuffCodeLengthArray, 0, 0);
}
예제 #2
0
void  BuildHuffmanTree( UINT32 RootIndex, UINT32 HIndex, UINT32 * FreqList )
{   
    HUFF_ENTRY * entry_ptr;
    HUFF_ENTRY * search_ptr;
	HUFF_ENTRY ** HuffRoot;

	// Select the Huffmant tree root.
	if ( RootIndex < 2 )
		HuffRoot = HuffRoot_VP31;
	else
		HuffRoot = HuffRoot_VP33;

    /* First create a sorted linked list representing the frequencies of each token. */
    CreateHuffmanList( HuffRoot, HIndex, FreqList );
    
    /* Now build the tree from the list. */
     
    /* While there are at least two items left in the list. */ 
    while ( HuffRoot[HIndex]->Next != NULL )
    {                              
        /* Create the new node as the parent of the first two in the list. */
        //entry_ptr = GlobalAlloc( GPTR, sizeof(HUFF_ENTRY) );   
        entry_ptr = (HUFF_ENTRY *)SytemGlobalAlloc( sizeof(HUFF_ENTRY) );
		if ( entry_ptr == NULL )
            IssueWarning( "Allocation Error in BuildHuffman" );

        entry_ptr->Value = -1;
        entry_ptr->Frequency = HuffRoot[HIndex]->Frequency + ( ((HUFF_ENTRY *)HuffRoot[HIndex]->Next)->Frequency );
        entry_ptr->ZeroChild = (char *)HuffRoot[HIndex];
        entry_ptr->OneChild = (char *)(HuffRoot[HIndex]->Next);  
        
        /* If there are still more items in the list then insert the new node into the list. */  
        if ( ((HUFF_ENTRY *)entry_ptr->OneChild)->Next != NULL )
        {   
            /* Set up the provisional 'new root' */ 
            HuffRoot[HIndex] = (HUFF_ENTRY *)( ((HUFF_ENTRY *)entry_ptr->OneChild)->Next );
            HuffRoot[HIndex]->Previous = NULL;
            
            /* Now scan through the remaining list to insert the new entry at the appropriate point. */
            if ( entry_ptr->Frequency <= HuffRoot[HIndex]->Frequency )
            {                                            
                entry_ptr->Next = (char * )HuffRoot[HIndex];  
                HuffRoot[HIndex]->Previous = (char * )entry_ptr;
                entry_ptr->Previous = (char * )NULL;   
                HuffRoot[HIndex] = entry_ptr;
            }
            else
            {  
                search_ptr = HuffRoot[HIndex];
                while ( (search_ptr->Next != NULL) && 
                        (search_ptr->Frequency < entry_ptr->Frequency) )
                {                                                                                  
                    search_ptr = (HUFF_ENTRY *)search_ptr->Next;
                }
                
                if ( search_ptr->Frequency < entry_ptr->Frequency )
                {
                    entry_ptr->Next = (char * )NULL;
                    entry_ptr->Previous = (char * )search_ptr;   
                    search_ptr->Next = (char * )entry_ptr;
                }
                else
                {
                    entry_ptr->Next = (char * )search_ptr;
                    entry_ptr->Previous = search_ptr->Previous; 
                    ((HUFF_ENTRY *)(search_ptr->Previous))->Next = (char * )entry_ptr;
                    search_ptr->Previous = (char * )entry_ptr;
                }
            }                                     
        }                                                                                      
        else
        {   
            /* Build has finished. */ 
            entry_ptr->Next = NULL;
            entry_ptr->Previous = NULL;
            HuffRoot[HIndex] = entry_ptr;
        }
        
        /* Delete the Next/Previous properties of the children (PROB NOT NEC). */ 
        ((HUFF_ENTRY *)entry_ptr->ZeroChild)->Next = NULL;
        ((HUFF_ENTRY *)entry_ptr->ZeroChild)->Previous = NULL;
        ((HUFF_ENTRY *)entry_ptr->OneChild)->Next = NULL;
        ((HUFF_ENTRY *)entry_ptr->OneChild)->Previous = NULL;
        
    } 
    
    /* Now build a code array from the tree. */
	if ( RootIndex < 2 )
		CreateCodeArray( HuffRoot[HIndex], HuffCodeArray_VP31[HIndex], HuffCodeLengthArray_VP31[HIndex], 0, 0);
	else
		CreateCodeArray( HuffRoot[HIndex], HuffCodeArray_VP33[HIndex], HuffCodeLengthArray_VP33[HIndex], 0, 0);
}