/* this function insert an item to a huffman tree. */ void libmpq__huffman_insert_item(struct huffman_tree_item_s **p_item, struct huffman_tree_item_s *item, uint32_t where, struct huffman_tree_item_s *item2) { /* EDI - next to the first item. */ struct huffman_tree_item_s *next = item->next; /* ESI - prev to the first item. */ struct huffman_tree_item_s *prev = item->prev; /* pointer to previous item. */ struct huffman_tree_item_s *prev2; /* pointer to next item. */ long next2; /* check the first item already has next one. */ if (next != 0) { /* check if previous item exist. */ if (PTR_INT(prev) < 0) { /* return previous item. */ prev = PTR_NOT(prev); } else { /* add item. */ prev += (item - next->prev); } /* 150083C1 - remove the item from the tree. */ prev->next = next; next->prev = prev; /* invalidate prev and next pointer. */ item->next = 0; item->prev = 0; } /* EDX - check if the second item is not entered. */ if (item2 == NULL) { /* take the first tree item. */ item2 = PTR_PTR(&p_item[1]); } /* check if items should be switched or new one inserted. */ switch (where) { case SWITCH_ITEMS: /* item2->next (pointer to pointer to first). */ item->next = item2->next; item->prev = item2->next->prev; item2->next->prev = item; /* set the first item. */ item2->next = item; /* return from function. */ return; case INSERT_ITEM: /* set next item (or pointer to pointer to first item) - insert as last item. */ item->next = item2; /* set previous item (or last item in the tree). */ item->prev = item2->prev; /* usually NULL. */ next2 = PTR_INT(p_item[0]); /* previous item to the second (or last tree item). */ prev2 = item2->prev; /* check if previous item is a valid pointer. */ if (PTR_INT(prev2) < 0) { /* set values. */ prev2 = PTR_NOT(prev); prev2->next = item; /* next after last item. */ item2->prev = item; /* return from function. */ return; } /* check if next item is empty. */ if (next2 < 0) { /* set next item. */ next2 = item2 - item2->next->prev; } /* add next item to previous one. */ prev2 += next2; prev2->next = item; /* set the next and last item. */ item2->prev = item; /* return from function. */ return; default: /* nothing to do, so return from function. */ return; } }
static struct huffman_tree_item *libmpq_huff_call1500E740(struct huffman_tree *ht, unsigned int value) { struct huffman_tree_item *p_item1 = ht->item3058; /* EDX */ struct huffman_tree_item *p_item2; /* EAX */ struct huffman_tree_item *p_next; struct huffman_tree_item *p_prev; struct huffman_tree_item **pp_item; if (PTR_INT(p_item1) <= 0 || (p_item2 = p_item1) == NULL) { if((p_item2 = &ht->items0008[ht->items++]) != NULL) { p_item1 = p_item2; } else { p_item1 = ht->first; } } else { p_item1 = p_item2; } p_next = p_item1->next; if (p_next != NULL) { p_prev = p_item1->prev; if (PTR_INT(p_prev) <= 0) { p_prev = PTR_NOT(p_prev); } else { p_prev += (p_item1 - p_item1->next->prev); } p_prev->next = p_next; p_next->prev = p_prev; p_item1->next = NULL; p_item1->prev = NULL; } pp_item = &ht->first; /* ESI */ if (value > 1) { /* ECX = ht->first->next; */ p_item1->next = *pp_item; p_item1->prev = (*pp_item)->prev; (*pp_item)->prev = p_item2; *pp_item = p_item1; p_item2->parent = NULL; p_item2->child = NULL; } else { p_item1->next = (struct huffman_tree_item *)pp_item; p_item1->prev = pp_item[1]; /* EDI = ht->item305C; */ p_prev = pp_item[1]; /* ECX */ if (p_prev <= 0) { p_prev = PTR_NOT(p_prev); p_prev->next = p_item1; p_prev->prev = p_item2; p_item2->parent = NULL; p_item2->child = NULL; } else { if (PTR_INT(ht->item305C) < 0) { p_prev += (struct huffman_tree_item *)pp_item - (*pp_item)->prev; } else { p_prev += PTR_INT(ht->item305C); } p_prev->next = p_item1; pp_item[1] = p_item2; p_item2->parent = NULL; p_item2->child = NULL; } } return p_item2; }
static void libmpq_huff_insert_item(struct huffman_tree_item** p_item, struct huffman_tree_item* item, unsigned long where, struct huffman_tree_item* item2) { struct huffman_tree_item* next = item->next; /* EDI - next to the first item */ struct huffman_tree_item* prev = item->prev; /* ESI - prev to the first item */ struct huffman_tree_item* prev2; /* Pointer to previous item */ long next2; /* Pointer to the next item */ /* The same code like in mpq_huff_remove_item(); */ if (next != 0) /* If the first item already has next one */ { if (PTR_INT(prev) < 0) { prev = PTR_NOT(prev); } else { prev += (item - next->prev); } /* * 150083C1 * Remove the item from the tree */ prev->next = next; next->prev = prev; /* Invalidate 'prev' and 'next' pointer */ item->next = 0; item->prev = 0; } if (item2 == NULL) /* EDX - If the second item is not entered, */ { item2 = PTR_PTR(&p_item[1]); /* take the first tree item */ } switch (where) { case SWITCH_ITEMS: /* Switch the two items */ item->next = item2->next; /* item2->next (Pointer to pointer to first) */ item->prev = item2->next->prev; item2->next->prev = item; item2->next = item; /* Set the first item */ return; case INSERT_ITEM: /* Insert as the last item */ item->next = item2; /* Set next item (or pointer to pointer to first item) */ item->prev = item2->prev; /* Set prev item (or last item in the tree) */ next2 = PTR_INT(p_item[0]); /* Usually NULL */ prev2 = item2->prev; /* Prev item to the second (or last tree item) */ if (PTR_INT(prev2) < 0) { prev2 = PTR_NOT(prev); prev2->next = item; item2->prev = item; /* Next after last item */ return; } if (next2 < 0) { next2 = item2 - item2->next->prev; } prev2 += next2; prev2->next = item; item2->prev = item; /* Set the next/last item */ return; default: return; } }
THTreeItem * THuffmannTree::Call1500E740(unsigned int nValue) { THTreeItem * pItem1 = pItem3058; // EDX THTreeItem * pItem2; // EAX THTreeItem * pNext; THTreeItem * pPrev; THTreeItem ** ppItem; if(PTR_INVALID_OR_NULL(pItem1) || (pItem2 = pItem1) == NULL) { if((pItem2 = &items0008[nItems++]) != NULL) pItem1 = pItem2; else pItem1 = pFirst; } else pItem1 = pItem2; pNext = pItem1->next; if(pNext != NULL) { pPrev = pItem1->prev; if(PTR_INVALID(pPrev)) pPrev = PTR_NOT(pPrev); else pPrev += (pItem1 - pItem1->next->prev); pPrev->next = pNext; pNext->prev = pPrev; pItem1->next = NULL; pItem1->prev = NULL; } ppItem = &pFirst; // esi if(nValue > 1) { // ecx = pFirst->next; pItem1->next = *ppItem; pItem1->prev = (*ppItem)->prev; (*ppItem)->prev = pItem2; *ppItem = pItem1; pItem2->parent = NULL; pItem2->child = NULL; } else { pItem1->next = (THTreeItem *)ppItem; pItem1->prev = ppItem[1]; // edi = pItem305C; pPrev = ppItem[1]; // ecx if(PTR_INVALID(pPrev)) { pPrev = PTR_NOT(pPrev); pPrev->next = pItem1; pPrev->prev = pItem2; pItem2->parent = NULL; pItem2->child = NULL; } else { if(PTR_INVALID(pItem305C)) pPrev += (THTreeItem *)ppItem - (*ppItem)->prev; else pPrev += (long)pItem305C; pPrev->next = pItem1; ppItem[1] = pItem2; pItem2->parent = NULL; pItem2->child = NULL; } } return pItem2; }
// Inserts item into the tree (?) static void InsertItem(THTreeItem ** itemPtr, THTreeItem * item, unsigned long where, THTreeItem * item2) { THTreeItem * next = item->next; // EDI - next to the first item THTreeItem * prev = item->prev; // ESI - prev to the first item THTreeItem * prev2; // Pointer to previous item THTreeItem * next2; // Pointer to the next item // The same code like in RemoveItem(item); if(next != 0) // If the first item already has next one { if(PTR_INVALID(prev)) prev = PTR_NOT(prev); else prev += (item - next->prev); // 150083C1 // Remove the item from the tree prev->next = next; next->prev = prev; // Invalidate 'prev' and 'next' pointer item->next = 0; item->prev = 0; } if(item2 == NULL) // EDX - If the second item is not entered, item2 = PTR_PTR(&itemPtr[1]); // take the first tree item switch(where) { case SWITCH_ITEMS : // Switch the two items item->next = item2->next; // item2->next (Pointer to pointer to first) item->prev = item2->next->prev; item2->next->prev = item; item2->next = item; // Set the first item return; case INSERT_ITEM: // Insert as the last item item->next = item2; // Set next item (or pointer to pointer to first item) item->prev = item2->prev; // Set prev item (or last item in the tree) next2 = itemPtr[0];// Usually NULL prev2 = item2->prev; // Prev item to the second (or last tree item) if(PTR_INVALID(prev2)) { prev2 = PTR_NOT(prev); prev2->next = item; item2->prev = item; // Next after last item return; } if(PTR_INVALID(next2)) next2 = (THTreeItem *)(item2 - item2->next->prev); prev2 += (long) next2; prev2->next = item; item2->prev = item; // Set the next/last item return; default: return; } }
/* return struct for 1500E740. */ struct huffman_tree_item_s *libmpq__huffman_call_1500E740(struct huffman_tree_s *ht) { /* EDX */ struct huffman_tree_item_s *p_item1 = ht->item3058; /* EAX */ struct huffman_tree_item_s *p_item2; /* some common variables. */ struct huffman_tree_item_s *p_next; struct huffman_tree_item_s *p_prev; struct huffman_tree_item_s **pp_item; /* check if item is empty. */ if (PTR_INT(p_item1) <= 0 || (p_item2 = p_item1) == NULL) { /* check if item is not empty. */ if ((p_item2 = &ht->items0008[ht->items++]) != NULL) { p_item1 = p_item2; } else { p_item1 = ht->first; } } else { p_item1 = p_item2; } /* set next item. */ p_next = p_item1->next; /* check if next item is not empty. */ if (p_next != NULL) { /* set previous item. */ p_prev = p_item1->prev; /* check if previous item is a valid pointer. */ if (PTR_INT(p_prev) <= 0) { p_prev = PTR_NOT(p_prev); } else { p_prev += (p_item1 - p_item1->next->prev); } /* fill values. */ p_prev->next = p_next; p_next->prev = p_prev; p_item1->next = NULL; p_item1->prev = NULL; } /* ESI */ pp_item = &ht->first; p_item1->next = (struct huffman_tree_item_s *)pp_item; p_item1->prev = pp_item[1]; /* EDI = ht->item305C - ECX */ p_prev = pp_item[1]; /* check if previous pointer is valid. */ if (p_prev <= 0) { /* fill values. */ p_prev = PTR_NOT(p_prev); p_prev->next = p_item1; p_prev->prev = p_item2; p_item2->parent = NULL; p_item2->child = NULL; } else { /* check if pointer is valid. */ if (PTR_INT(ht->item305C) < 0) { p_prev += (struct huffman_tree_item_s *)pp_item - (*pp_item)->prev; } else { p_prev += PTR_INT(ht->item305C); } /* fill values. */ p_prev->next = p_item1; pp_item[1] = p_item2; p_item2->parent = NULL; p_item2->child = NULL; } /* return item. */ return p_item2; }