static void CreateCodeArray( HUFF_ENTRY * HuffRoot, ogg_uint32_t *HuffCodeArray, unsigned char *HuffCodeLengthArray, ogg_uint32_t CodeValue, unsigned char CodeLength ) { /* If we are at a leaf then fill in a code array entry. */ if ( ( HuffRoot->ZeroChild == NULL ) && ( HuffRoot->OneChild == NULL ) ){ HuffCodeArray[HuffRoot->Value] = CodeValue; HuffCodeLengthArray[HuffRoot->Value] = CodeLength; }else{ /* Recursive calls to scan down the tree. */ CodeLength++; CreateCodeArray(HuffRoot->ZeroChild, HuffCodeArray, HuffCodeLengthArray, ((CodeValue << 1) + 0), CodeLength); CreateCodeArray(HuffRoot->OneChild, HuffCodeArray, HuffCodeLengthArray, ((CodeValue << 1) + 1), CodeLength); } }
/**************************************************************************** * * ROUTINE : CreateCodeArray * * INPUTS : The tree root * A HuffCodeArray * A HuffCodeLengthArray * The code value of the root. * The length of the code in bits. * * OUTPUTS : * * RETURNS : * * FUNCTION : This funtion creates the code array from the huffman tree * that is used to code tokens. * * SPECIAL NOTES : None. * * * ERRORS : None. * ****************************************************************************/ void CreateCodeArray( HUFF_ENTRY * HuffRoot, UINT32 * HuffCodeArray, UINT8 * HuffCodeLengthArray, UINT32 CodeValue, UINT8 CodeLength ) { /* If we are at a leaf then fill in a code array entry. */ if ( ( HuffRoot->ZeroChild == NULL ) && ( HuffRoot->OneChild == NULL ) ) { HuffCodeArray[HuffRoot->Value] = CodeValue; HuffCodeLengthArray[HuffRoot->Value] = CodeLength; } else { /* Recursive calls to scan down the tree. */ CreateCodeArray( (HUFF_ENTRY *)(HuffRoot->ZeroChild), HuffCodeArray, HuffCodeLengthArray, ((CodeValue << 1) + 0), (UINT8)(CodeLength + 1) ); CreateCodeArray( (HUFF_ENTRY *)(HuffRoot->OneChild), HuffCodeArray, HuffCodeLengthArray, ((CodeValue << 1) + 1), (UINT8)(CodeLength + 1) ); } }
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); }
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); }