📄 huffman.cpp
字号:
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 = long(item2 - item2->next->prev); } prev2 += next2; prev2->next = item; item2->prev = item; /* Set the next/last item */ return; default: return; }}/* Builds Huffman tree. Called with the first 8 bits loaded from input stream. */static void libmpq_huff_build_tree(struct huffman_tree *ht, unsigned int cmp_type) { unsigned long max_byte; /* [ESP+10] - The greatest character found in table */ unsigned char *byte_array; /* [ESP+1C] - Pointer to unsigned char in table1502A630 */ unsigned long i; /* egcs in linux doesn't like multiple for loops without an explicit i */ unsigned int found; /* Thats needed to replace the goto stuff from original source :) */ struct huffman_tree_item **p_item; /* [ESP+14] - Pointer to Huffman tree item pointer array */ struct huffman_tree_item *child1; /* Loop while pointer has a negative value. */ while (PTR_INT(ht->last) > 0) { /* ESI - Last entry */ struct huffman_tree_item *temp; /* EAX */ if (ht->last->next != NULL) { /* ESI->next */ libmpq_huff_remove_item(ht->last); } ht->item3058 = PTR_PTR(&ht->item3054);/* [EDI+4] */ ht->last->prev = ht->item3058; /* EAX */ temp = libmpq_huff_get_prev_item(PTR_PTR(&ht->item3054), PTR_INT(&ht->item3050)); temp->next = ht->last; ht->item3054 = ht->last; } /* Clear all pointers in huffman tree item array. */ memset(ht->items306C, 0, sizeof(ht->items306C)); max_byte = 0; /* Greatest character found init to zero. */ p_item = (struct huffman_tree_item **)&ht->items306C; /* Pointer to current entry in huffman tree item pointer array */ /* Ensure we have low 8 bits only */ cmp_type &= 0xFF; byte_array = table1502A630 + cmp_type * 258; /* EDI also */ for (i = 0; i < 0x100; i++, p_item++) { struct huffman_tree_item *item = ht->item3058; /* Item to be created */ struct huffman_tree_item *p_item3 = ht->item3058; unsigned char one_byte = byte_array[i]; /* Skip all the bytes which are zero. */ if (byte_array[i] == 0) { continue; } /* If not valid pointer, take the first available item in the array. */ if (PTR_INT(item) <= 0) { item = &ht->items0008[ht->items++]; } /* Insert this item as the top of the tree. */ libmpq_huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL); item->parent = NULL; /* Invalidate child and parent */ item->child = NULL; *p_item = item; /* Store pointer into pointer array */ item->dcmp_byte = i; /* Store counter */ item->byte_value = one_byte; /* Store byte value */ if (one_byte >= max_byte) { max_byte = one_byte; continue; } /* Find the first item which has byte value greater than current one byte */ found = 0; if (PTR_INT((p_item3 = ht->last)) > 0) {/* EDI - Pointer to the last item */ /* 15006AF7 */ if (p_item3 != NULL) { do { /* 15006AFB */ if (p_item3->byte_value >= one_byte) { found = 1; break; } p_item3 = p_item3->prev; } while (PTR_INT(p_item3) > 0); } } if (found == 0) { p_item3 = NULL; } /* 15006B09 */ if (item->next != NULL) { libmpq_huff_remove_item(item); } /* 15006B15 */ if (p_item3 == NULL) { p_item3 = PTR_PTR(&ht->first); } /* 15006B1F */ item->next = p_item3->next; item->prev = p_item3->next->prev; p_item3->next->prev = item; p_item3->next = item; } /* 15006B4A */ for (; i < 0x102; i++) { struct huffman_tree_item **p_item2 = &ht->items306C[i]; /* EDI */ /* 15006B59 */ struct huffman_tree_item *item2 = ht->item3058; /* ESI */ if (PTR_INT(item2) <= 0) { item2 = &ht->items0008[ht->items++]; } libmpq_huff_insert_item(&ht->item305C, item2, INSERT_ITEM, NULL); /* 15006B89 */ item2->dcmp_byte = i; item2->byte_value = 1; item2->parent = NULL; item2->child = NULL; *p_item2++ = item2; } /* 15006BAA */ if (PTR_INT((child1 = ht->last)) > 0) { /* EDI - last item (first child to item */ struct huffman_tree_item *child2; /* EBP */ struct huffman_tree_item *item; /* ESI */ /* 15006BB8 */ while (PTR_INT((child2 = child1->prev)) > 0) { if (PTR_INT((item = ht->item3058)) <= 0) { item = &ht->items0008[ht->items++]; } /* 15006BE3 */ libmpq_huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL); /* 15006BF3 */ item->parent = NULL; item->child = NULL; /* * EDX = child2->byte_value + child1->byte_value; * EAX = child1->byte_value; * ECX = max_byte; The greatest character (0xFF usually) */ item->byte_value = child1->byte_value + child2->byte_value; /* 0x02 */ item->child = child1; /* Prev item in the */ child1->parent = item; child2->parent = item; /* EAX = item->byte_value; */ if (item->byte_value >= max_byte) { max_byte = item->byte_value; } else { struct huffman_tree_item *p_item2 = child2->prev; /* EDI */ found = 0; if (PTR_INT(p_item2) > 0) { /* 15006C2D */ do { if (p_item2->byte_value >= item->byte_value) { found = 1; break; } p_item2 = p_item2->prev; } while (PTR_INT(p_item2) > 0); } if (found == 0) { p_item2 = NULL; } if (item->next != 0) { struct huffman_tree_item *temp4 = libmpq_huff_get_prev_item(item, -1); temp4->next = item->next; /* The first item changed */ item->next->prev = item->prev; /* First->prev changed to negative value */ item->next = NULL; item->prev = NULL; } /* 15006C62 */ if (p_item2 == NULL) { p_item2 = PTR_PTR(&ht->first); } item->next = p_item2->next; /* Set item with 0x100 byte value */ item->prev = p_item2->next->prev; /* Set item with 0x17 byte value */ p_item2->next->prev = item; /* Changed prev of item with */ p_item2->next = item; } /* 15006C7B */ if (PTR_INT((child1 = child2->prev)) <= 0) { break; } } } /* 15006C88 */ ht->offs0004 = 1;}/* Gets the whole byte from the input stream. */static unsigned long libmpq_huff_get_8bits(struct huffman_input_stream *is) { unsigned long one_byte; if (is->bits <= 8) { is->bit_buf |= *(unsigned short *)is->in_buf << is->bits; is->in_buf += sizeof(unsigned short); is->bits += 16; } one_byte = (is->bit_buf & 0xFF); is->bit_buf >>= 8; is->bits -= 8; return one_byte;}/* Gets 7 bits from the stream. */static unsigned long libmpq_huff_get_7bits(struct huffman_input_stream *is) { if (is->bits <= 7) { is->bit_buf |= *(unsigned short *)is->in_buf << is->bits; is->in_buf += sizeof(unsigned short); is->bits += 16; } /* Get 7 bits from input stream. */ return (is->bit_buf & 0x7F);}/* Gets one bit from input stream. */unsigned long libmpq_huff_get_bit(struct huffman_input_stream *is) { unsigned long bit = (is->bit_buf & 1); is->bit_buf >>= 1; if (--is->bits == 0) { is->bit_buf = *(unsigned long *)is->in_buf; is->in_buf += sizeof(unsigned long); is->bits = 32; } return bit;}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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -