Esempio n. 1
0
void THuffmannTree::InitTree(bool bCompression)
{
    THTreeItem * pItem;
    unsigned int nCount;

    // Clear links for all the items in the tree
    for(pItem = items0008, nCount = 0x203; nCount != 0; pItem++, nCount--)
        pItem->ClearItemLinks();

    pItem3050 = NULL;
    pItem3054 = PTR_PTR(&pItem3054);
    pItem3058 = PTR_NOT(pItem3054);

    pItem305C = NULL;
    pFirst    = PTR_PTR(&pFirst);
    pLast     = PTR_NOT(pFirst);

    offs0004  = 1;
    nItems    = 0;

    // Clear all TQDecompress items. Do this only if preparing for decompression
    if(bCompression == false)
    {
        for(nCount = 0; nCount < sizeof(qd3474) / sizeof(TQDecompress); nCount++)
            qd3474[nCount].offs00 = 0;
    }
}
Esempio n. 2
0
/* this function initialize a huffman tree. */
void libmpq__huffman_tree_init(struct huffman_tree_s *ht, uint32_t cmp) {

    /* some common variables. */
    uint32_t count;
    struct huffman_tree_item_s *hi;

    /* clear links for all the items in the tree. */
    for (hi = ht->items0008, count = 0x203; count != 0; hi++, count--) {
        hi->next = hi->prev = NULL;
    }

    /* fill values. */
    ht->item3050 = NULL;
    ht->item3054 = PTR_PTR(&ht->item3054);
    ht->item3058 = PTR_NOT(ht->item3054);
    ht->item305C = NULL;
    ht->first    = PTR_PTR(&ht->first);
    ht->last     = PTR_NOT(ht->first);
    ht->offs0004 = 1;
    ht->items    = 0;

    /* clear all huffman decompress items, do this only if preparing for decompression. */
    if (cmp == LIBMPQ_HUFF_DECOMPRESS) {
        for (count = 0; count < sizeof(ht->qd3474) / sizeof(struct huffman_decompress_s); count++) {
            ht->qd3474[count].offs00 = 0;
        }
    }
}
Esempio n. 3
0
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;
	}
}
Esempio n. 4
0
static void libmpq_huff_call1500E820(struct huffman_tree *ht, struct huffman_tree_item *p_item) {
	struct huffman_tree_item *p_item1;		/* EDI */
	struct huffman_tree_item *p_item2 = NULL;	/* EAX */
	struct huffman_tree_item *p_item3;		/* EDX */
	struct huffman_tree_item *p_prev;		/* EBX */

	for (; p_item != NULL; p_item = p_item->parent) {
		p_item->byte_value++;

		for (p_item1 = p_item; ; p_item1 = p_prev) {
			p_prev = p_item1->prev;
			if (PTR_INT(p_prev) <= 0) {
				p_prev = NULL;
				break;
			}
			if (p_prev->byte_value >= p_item->byte_value) {
				break;
			}
		}

		if (p_item1 == p_item) {
			continue;
		}

		if (p_item1->next != NULL) {
			p_item2 = libmpq_huff_get_prev_item(p_item1, -1);
			p_item2->next = p_item1->next;
			p_item1->next->prev = p_item1->prev;
			p_item1->next = NULL;
			p_item1->prev = NULL;
		}
		p_item2 = p_item->next;
		p_item1->next = p_item2;
		p_item1->prev = p_item2->prev;
		p_item2->prev = p_item1;
		p_item->next = p_item1;
		if ((p_item2 = p_item1) != NULL) {
			p_item2 = libmpq_huff_get_prev_item(p_item, -1);
			p_item2->next = p_item->next;
			p_item->next->prev = p_item->prev;
			p_item->next = NULL;
			p_item->prev = NULL;
		}

		if (p_prev == NULL) {
			p_prev = PTR_PTR(&ht->first);
		}
		p_item2       = p_prev->next;
		p_item->next  = p_item2;
		p_item->prev  = p_item2->prev;
		p_item2->prev = p_item;
		p_prev->next  = p_item;

		p_item3 = p_item1->parent->child;
		p_item2 = p_item->parent;
		if (p_item2->child == p_item) {
			p_item2->child = p_item1;
		}

		if (p_item3 == p_item1) {
			p_item1->parent->child = p_item;
		}

		p_item2 = p_item->parent;
		p_item->parent  = p_item1->parent;
		p_item1->parent = p_item2;
		ht->offs0004++;
	}
}
Esempio n. 5
0
/* 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;
}
Esempio n. 6
0
/* this function build a huffman tree, called with the first 8 bits loaded from input stream. */
void libmpq__huffman_tree_build(struct huffman_tree_s *ht, uint32_t cmp_type) {

    /* [ESP+10] - the greatest character found in table. */
    uint32_t max_byte;

    /* [ESP+1C] - pointer to uint8_t in table_1502A630. */
    const uint8_t *byte_array;

    /* thats needed to replace the goto stuff from original source. :) */
    uint32_t found;

    /* [ESP+14] - Pointer to Huffman tree item pointer array. */
    struct huffman_tree_item_s **p_item;
    struct huffman_tree_item_s *child1;

    /* some common variables. */
    uint32_t i;

    /* ESI - loop while pointer has a negative value (last entry). */
    while (PTR_INT(ht->last) > 0) {

        /* EAX */
        struct huffman_tree_item_s *temp;

        /* ESI->next */
        if (ht->last->next != NULL) {
            libmpq__huffman_remove_item(ht->last);
        }

        /* [EDI+4] */
        ht->item3058   = PTR_PTR(&ht->item3054);

        /* EAX */
        ht->last->prev = ht->item3058;
        temp           = libmpq__huffman_previous_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));

    /* greatest character found init to zero. */
    max_byte    = 0;

    /* pointer to current entry in huffman tree item pointer array. */
    p_item      = (struct huffman_tree_item_s **)&ht->items306C;

    /* ensure we have low 8 bits only. */
    cmp_type   &= 0xFF;

    /* EDI also. */
    byte_array  = table_1502A630 + cmp_type * 258;

    /* loop to build huffman tree. */
    for (i = 0; i < 0x100; i++, p_item++) {

        /* item to be created. */
        struct huffman_tree_item_s *item    = ht->item3058;
        struct huffman_tree_item_s *p_item3 = ht->item3058;
        uint8_t 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__huffman_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL);

        /* invalidate child and parent. */
        item->parent     = NULL;
        item->child      = NULL;

        /* store pointer into pointer array. */
        *p_item          = item;

        /* store counter. */
        item->dcmp_byte  = i;

        /* store byte value. */
        item->byte_value = one_byte;

        /* check if byte is to big. */
        if (one_byte >= max_byte) {

            /* set max byte to highest value. */
            max_byte = one_byte;

            /* continue loop. */
            continue;
        }

        /* find the first item which has byte value greater than current one byte. */
        found = 0;

        /* EDI - Pointer to the last item. */
        if (PTR_INT((p_item3 = ht->last)) > 0) {

            /* 15006AF7 */
            if (p_item3 != NULL) {

                /* 15006AFB */
                do {

                    /* check if we found item. */
                    if (p_item3->byte_value >= one_byte) {
                        found = 1;
                        break;
                    }

                    /* switch to previous item. */
                    p_item3 = p_item3->prev;
                } while (PTR_INT(p_item3) > 0);
            }
        }

        /* check if item was not found. */
        if (found == 0) {
            p_item3 = NULL;
        }

        /* 15006B09 */
        if (item->next != NULL) {
            libmpq__huffman_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++) {

        /* EDI */
        struct huffman_tree_item_s **p_item2 = &ht->items306C[i];

        /* 15006B59 - ESI */
        struct huffman_tree_item_s *item2 = ht->item3058;

        /* check if item is a valid pointer. */
        if (PTR_INT(item2) <= 0) {
            item2 = &ht->items0008[ht->items++];
        }

        /* insert the item into tree. */
        libmpq__huffman_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 - EDI - last item (first child to item). */
    if (PTR_INT((child1 = ht->last)) > 0) {

        /* EBP */
        struct huffman_tree_item_s *child2;

        /* ESI */
        struct huffman_tree_item_s *item;

        /* 15006BB8 */
        while (PTR_INT((child2 = child1->prev)) > 0) {
            if (PTR_INT((item = ht->item3058)) <= 0) {
                item = &ht->items0008[ht->items++];
            }

            /* 15006BE3 */
            libmpq__huffman_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 (0x02 usually)
             */
            item->byte_value = child1->byte_value + child2->byte_value;

            /* previous item in the tree. */
            item->child      = child1;
            child1->parent   = item;
            child2->parent   = item;

            /* EAX = item->byte_value */
            if (item->byte_value >= max_byte) {
                max_byte = item->byte_value;
            } else {

                /* EDI */
                struct huffman_tree_item_s *p_item2 = child2->prev;
                found = 0;

                /* check if item is a valid pointer. */
                if (PTR_INT(p_item2) > 0) {

                    /* 15006C2D */
                    do {

                        /* check if we found item. */
                        if (p_item2->byte_value >= item->byte_value) {
                            found = 1;
                            break;
                        }

                        /* switch to previous item. */
                        p_item2 = p_item2->prev;
                    } while (PTR_INT(p_item2) > 0);
                }

                /* check if item was not found. */
                if (found == 0) {
                    p_item2 = NULL;
                }

                /* check if next item exist. */
                if (item->next != 0) {

                    /* some common variables. */
                    struct huffman_tree_item_s *temp4 = libmpq__huffman_previous_item(item, -1);

                    /* zhe first item changed. */
                    temp4->next                     = item->next;

                    /* first->prev changed to negative value. */
                    item->next->prev                = item->prev;
                    item->next                      = NULL;
                    item->prev                      = NULL;
                }

                /* 15006C62 */
                if (p_item2 == NULL) {
                    p_item2 = PTR_PTR(&ht->first);
                }

                /* set item with 0x100 byte value. */
                item->next          = p_item2->next;

                /* set item with 0x17 byte value. */
                item->prev          = p_item2->next->prev;

                /* changed prev of item with. */
                p_item2->next->prev = item;
                p_item2->next       = item;
            }

            /* 15006C7B */
            if (PTR_INT((child1 = child2->prev)) <= 0) {
                break;
            }
        }
    }

    /* 15006C88 */
    ht->offs0004 = 1;
}
Esempio n. 7
0
/* return struct for 1500E820. */
void libmpq__huffman_call_1500E820(struct huffman_tree_s *ht, struct huffman_tree_item_s *p_item) {

    /* EDI */
    struct huffman_tree_item_s *p_item1;

    /* EAX */
    struct huffman_tree_item_s *p_item2 = NULL;

    /* EDX */
    struct huffman_tree_item_s *p_item3;

    /* EBX */
    struct huffman_tree_item_s *p_prev;

    /* loop through parent items. */
    for (; p_item != NULL; p_item = p_item->parent) {

        /* increase byte counter. */
        p_item->byte_value++;

        /* loop through previous items. */
        for (p_item1 = p_item; ; p_item1 = p_prev) {

            /* set previous item. */
            p_prev = p_item1->prev;

            /* check if pointer is valid. */
            if (PTR_INT(p_prev) <= 0) {
                p_prev = NULL;
                break;
            }

            /* check if byte value of previous item is higher than actual item. */
            if (p_prev->byte_value >= p_item->byte_value) {
                break;
            }
        }

        /* check if previous item is same like actual item. */
        if (p_item1 == p_item) {
            continue;
        }

        /* check if next item is not empty, */
        if (p_item1->next != NULL) {

            /* fill values. */
            p_item2             = libmpq__huffman_previous_item(p_item1, -1);
            p_item2->next       = p_item1->next;
            p_item1->next->prev = p_item1->prev;
            p_item1->next       = NULL;
            p_item1->prev       = NULL;
        }

        /* fill values. */
        p_item2       = p_item->next;
        p_item1->next = p_item2;
        p_item1->prev = p_item2->prev;
        p_item2->prev = p_item1;
        p_item->next  = p_item1;

        /* check if both items are not empty. */
        if ((p_item2 = p_item1) != NULL) {

            /* fill values. */
            p_item2            = libmpq__huffman_previous_item(p_item, -1);
            p_item2->next      = p_item->next;
            p_item->next->prev = p_item->prev;
            p_item->next       = NULL;
            p_item->prev       = NULL;
        }

        /* check if previous item is empty. */
        if (p_prev == NULL) {
            p_prev = PTR_PTR(&ht->first);
        }

        /* fill values. */
        p_item2       = p_prev->next;
        p_item->next  = p_item2;
        p_item->prev  = p_item2->prev;
        p_item2->prev = p_item;
        p_prev->next  = p_item;
        p_item3       = p_item1->parent->child;
        p_item2       = p_item->parent;

        /* check if child item and parent item match. */
        if (p_item2->child == p_item) {
            p_item2->child = p_item1;
        }

        /* check if items match. */
        if (p_item3 == p_item1) {
            p_item1->parent->child = p_item;
        }

        /* fill values. */
        p_item2         = p_item->parent;
        p_item->parent  = p_item1->parent;
        p_item1->parent = p_item2;

        /* increase counter. */
        ht->offs0004++;
    }
}
Esempio n. 8
0
/* 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;
    }
}
Esempio n. 9
0
void THuffmannTree::Call1500E820(THTreeItem * pItem)
{
    THTreeItem * pItem1;                // edi
    THTreeItem * pItem2 = NULL;         // eax
    THTreeItem * pItem3;                // edx
    THTreeItem * pPrev;                 // ebx

    for(; pItem != NULL; pItem = pItem->parent)
    {
        pItem->byteValue++;

        for(pItem1 = pItem; ; pItem1 = pPrev)
        {
            pPrev = pItem1->prev;
            if(PTR_INVALID_OR_NULL(pPrev))
            {
                pPrev = NULL;
                break;
            }

            if(pPrev->byteValue >= pItem->byteValue)
                break;
        }

        if(pItem1 == pItem)
            continue;

        if(pItem1->next != NULL)
        {
            pItem2 = pItem1->GetPrevItem(-1);
            pItem2->next = pItem1->next;
            pItem1->next->prev = pItem1->prev;
            pItem1->next = NULL;
            pItem1->prev = NULL;
        }

        pItem2 = pItem->next;
        pItem1->next = pItem2;
        pItem1->prev = pItem2->prev;
        pItem2->prev = pItem1;
        pItem->next = pItem1;
        if((pItem2 = pItem1) != NULL)
        {
            pItem2 = pItem->GetPrevItem(-1);
            pItem2->next = pItem->next;
            pItem->next->prev = pItem->prev;
            pItem->next = NULL;
            pItem->prev = NULL;
        }

        if(pPrev == NULL)
            pPrev = PTR_PTR(&pFirst);

        pItem2       = pPrev->next;
        pItem->next  = pItem2;
        pItem->prev  = pItem2->prev;
        pItem2->prev = pItem;
        pPrev->next  = pItem;

        pItem3 = pItem1->parent->child;
        pItem2 = pItem->parent;
        if(pItem2->child == pItem)
            pItem2->child = pItem1;
        if(pItem3 == pItem1)
            pItem1->parent->child = pItem;

        pItem2 = pItem->parent;
        pItem->parent  = pItem1->parent;
        pItem1->parent = pItem2;
        offs0004++;
    }
}
Esempio n. 10
0
// Builds Huffman tree. Called with the first 8 bits loaded from input stream
void THuffmannTree::BuildTree(unsigned int nCmpType)
{
    unsigned long   maxByte;                // [ESP+10] - The greatest character found in table
    THTreeItem   ** itemPtr;                // [ESP+14] - Pointer to Huffman tree item pointer array
    unsigned char * byteArray;              // [ESP+1C] - Pointer to unsigned char in Table1502A630
    THTreeItem    * child1;
    unsigned long   i;                      // egcs in linux doesn't like multiple for loops without an explicit i

    // Loop while pointer has a valid value
    while(PTR_VALID(pLast))                 // ESI - Last entry
    {
        THTreeItem * temp;                  // EAX

        if(pLast->next != NULL)             // ESI->next
            pLast->RemoveItem();
                                            // EDI = &offs3054
        pItem3058   = PTR_PTR(&pItem3054);  // [EDI+4]
        pLast->prev = pItem3058;            // EAX

        temp = PTR_PTR(&pItem3054)->GetPrevItem(PTR_INT(&pItem3050));

        temp->next = pLast;
        pItem3054  = pLast;
    }

    // Clear all pointers in HTree item array
    memset(items306C, 0, sizeof(items306C));

    maxByte = 0;                            // Greatest character found init to zero.
    itemPtr = (THTreeItem **)&items306C;    // Pointer to current entry in HTree item pointer array

    // Ensure we have low 8 bits only
    nCmpType &= 0xFF;
    byteArray  = Table1502A630 + nCmpType * 258; // EDI also

    for(i = 0; i < 0x100; i++, itemPtr++)
    {
        THTreeItem * item   = pItem3058;    // Item to be created
        THTreeItem * pItem3 = pItem3058;
        unsigned char         oneByte = byteArray[i];

        // Skip all the bytes which are zero.
        if(byteArray[i] == 0)
            continue;

        // If not valid pointer, take the first available item in the array
        if(PTR_INVALID_OR_NULL(item))
            item = &items0008[nItems++];

        // Insert this item as the top of the tree
        InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL);

        item->parent    = NULL;                 // Invalidate child and parent
        item->child     = NULL;
        *itemPtr        = item;                 // Store pointer into pointer array

        item->dcmpByte  = i;                    // Store counter
        item->byteValue = oneByte;              // Store byte value
        if(oneByte >= maxByte)
        {
            maxByte = oneByte;
            continue;
        }

        // Find the first item which has byte value greater than current one byte
        if(PTR_VALID(pItem3 = pLast))           // EDI - Pointer to the last item
        {
            // 15006AF7
            if(pItem3 != NULL)
            {
                do  // 15006AFB
                {
                    if(pItem3->byteValue >= oneByte)
                        goto _15006B09;
                    pItem3 = pItem3->prev;
                }
                while(PTR_VALID(pItem3));
            }
        }
        pItem3 = NULL;

        // 15006B09
        _15006B09:
        if(item->next != NULL)
            item->RemoveItem();

        // 15006B15
        if(pItem3 == NULL)
            pItem3 = PTR_PTR(&pFirst);

        // 15006B1F
        item->next = pItem3->next;
        item->prev = pItem3->next->prev;
        pItem3->next->prev = item;
        pItem3->next = item;
    }

    // 15006B4A
    for(; i < 0x102; i++)
    {
        THTreeItem ** itemPtr = &items306C[i];  // EDI

        // 15006B59
        THTreeItem * item = pItem3058;          // ESI
        if(PTR_INVALID_OR_NULL(item))
            item = &items0008[nItems++];

        InsertItem(&pItem305C, item, INSERT_ITEM, NULL);

        // 15006B89
        item->dcmpByte   = i;
        item->byteValue  = 1;
        item->parent     = NULL;
        item->child      = NULL;
        *itemPtr++ = item;
    }

    // 15006BAA
    if(PTR_VALID(child1 = pLast))                   // EDI - last item (first child to item
    {
        THTreeItem * child2;                        // EBP
        THTreeItem * item;                          // ESI

        // 15006BB8
        while(PTR_VALID(child2 = child1->prev))
        {
            if(PTR_INVALID_OR_NULL(item = pItem3058))
                item = &items0008[nItems++];

            // 15006BE3
            InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL);

            // 15006BF3
            item->parent = NULL;
            item->child  = NULL;

            //EDX = child2->byteValue + child1->byteValue;
            //EAX = child1->byteValue;
            //ECX = maxByte;                        // The greatest character (0xFF usually)

            item->byteValue = child1->byteValue + child2->byteValue; // 0x02
            item->child     = child1;                                // Prev item in the
            child1->parent  = item;
            child2->parent  = item;

            // EAX = item->byteValue;
            if(item->byteValue >= maxByte)
                maxByte = item->byteValue;
            else
            {
                THTreeItem * pItem2 = child2->prev;   // EDI

                // 15006C2D
                while(PTR_VALID(pItem2))
                {
                    if(pItem2->byteValue >= item->byteValue)
                        goto _15006C3B;
                    pItem2 = pItem2->prev;
                }
                pItem2 = NULL;

                _15006C3B:
                if(item->next != 0)
                {
                    THTreeItem * temp4 = item->GetPrevItem(-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(pItem2 == NULL)
                    pItem2 = PTR_PTR(&pFirst);

                item->next = pItem2->next;                           // Set item with 0x100 byte value
                item->prev = pItem2->next->prev;                     // Set item with 0x17 byte value
                pItem2->next->prev = item;                           // Changed prev of item with
                pItem2->next = item;
            }

            // 15006C7B
            if(PTR_INVALID_OR_NULL(child1 = child2->prev))
                break;
        }
    }
    // 15006C88
    offs0004 = 1;
}
Esempio n. 11
0
// Inserts item into the tree (?)
static void InsertItem(THTreeItem ** itemPtr, THTreeItem * item, unsigned long nWhere, 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
    LONG_PTR 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(nWhere)
    {
        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(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 = (LONG_PTR)(item2 - item2->next->prev);
//              next2 = (THTreeItem *)(unsigned long)((unsigned char *)item2 - (unsigned char *)(item2->next->prev));

//          prev2 = (THTreeItem *)((char *)prev2 + (unsigned long)next2);// ???
            prev2 += next2;
            prev2->next = item;
            item2->prev = item;         // Set the next/last item
            return;

        default:
            return;
    }
}