aboutsummaryrefslogtreecommitdiff
path: root/src/huffman/huff_old.cpp
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avg.com>2013-01-11 14:55:08 +0100
committerLadislav Zezula <ladislav.zezula@avg.com>2013-01-11 14:55:08 +0100
commit3a926f0228c68d7d91cf3946624d7859976440ec (patch)
treec4e7d36dc8157576929988cdfcf5bfd8262cd09c /src/huffman/huff_old.cpp
parentdf4b0c085478389c9a21a09521d46735a0109c8a (diff)
Initial creation
Diffstat (limited to 'src/huffman/huff_old.cpp')
-rw-r--r--src/huffman/huff_old.cpp1303
1 files changed, 1303 insertions, 0 deletions
diff --git a/src/huffman/huff_old.cpp b/src/huffman/huff_old.cpp
new file mode 100644
index 0000000..66a46b3
--- /dev/null
+++ b/src/huffman/huff_old.cpp
@@ -0,0 +1,1303 @@
+/*****************************************************************************/
+/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */
+/*---------------------------------------------------------------------------*/
+/* This module contains Huffmann (de)compression methods */
+/* */
+/* Authors : Ladislav Zezula (ladik@zezula.net) */
+/* ShadowFlare (BlakFlare@hotmail.com) */
+/* */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */
+/* 03.05.03 1.00 Lad Added compression methods */
+/* 19.11.03 1.01 Dan Big endian handling */
+/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */
+/*****************************************************************************/
+
+#include <assert.h>
+#include <string.h>
+
+#include "huff.h"
+
+// Special for Mac - we have to know if normal pointer greater or less
+// than 0x80000000. This variable is used in the PTR_VALID and PTR_INVALID
+// macros
+static long mul = 1;
+
+#define PTR_VALID(ptr) (((LONG_PTR)(ptr) * mul) > 0)
+#define PTR_INVALID(ptr) (((LONG_PTR)(ptr) * mul) < 0)
+#define PTR_INVALID_OR_NULL(ptr) (((LONG_PTR)(ptr) * mul) <= 0)
+
+
+//-----------------------------------------------------------------------------
+// Methods of the THTreeItem struct
+
+// 1501DB70
+THTreeItem * THTreeItem::Call1501DB70(THTreeItem * pLast)
+{
+ if(pLast == NULL)
+ pLast = this + 1;
+ return pLast;
+}
+
+// Gets previous Huffman tree item (?)
+THTreeItem * THTreeItem::GetPrevItem(LONG_PTR value)
+{
+ if(PTR_INVALID(prev))
+ return PTR_NOT(prev);
+
+ if(value == -1 || PTR_INVALID(value))
+ value = (LONG_PTR)(this - next->prev);
+ return prev + value;
+
+// OLD VERSION
+// if(PTR_INT(value) < 0)
+// value = PTR_INT((item - item->next->prev));
+// return (THTreeItem *)((char *)prev + value);
+}
+
+// 1500F5E0
+void THTreeItem::ClearItemLinks()
+{
+ next = prev = NULL;
+}
+
+// 1500BC90
+void THTreeItem::RemoveItem()
+{
+ THTreeItem * pTemp; // EDX
+
+ if(next != NULL)
+ {
+ pTemp = prev;
+
+ if(PTR_INVALID_OR_NULL(pTemp))
+ pTemp = PTR_NOT(pTemp);
+ else
+ pTemp += (this - next->prev);
+
+ pTemp->next = next;
+ next->prev = prev;
+ next = prev = NULL;
+ }
+}
+
+/*
+// OLD VERSION : Removes item from the tree (?)
+static void RemoveItem(THTreeItem * item)
+{
+ THTreeItem * next = item->next; // ESI
+ THTreeItem * prev = item->prev; // EDX
+
+ if(next == NULL)
+ return;
+
+ if(PTR_INT(prev) < 0)
+ prev = PTR_NOT(prev);
+ else
+ // ??? usually item == next->prev, so what is it ?
+ prev = (THTreeItem *)((unsigned char *)prev + (unsigned long)((unsigned char *)item - (unsigned char *)(next->prev)));
+
+ // Remove HTree item from the chain
+ prev->next = next; // Sets the 'first' pointer
+ next->prev = item->prev;
+
+ // Invalidate pointers
+ item->next = NULL;
+ item->prev = NULL;
+}
+*/
+
+//-----------------------------------------------------------------------------
+// TOutputStream functions
+
+void TOutputStream::PutBits(unsigned long dwBuff, unsigned int nPutBits)
+{
+ dwBitBuff |= (dwBuff << nBits);
+ nBits += nPutBits;
+
+ // Flush completed bytes
+ while(nBits >= 8)
+ {
+ if(cbOutSize != 0)
+ {
+ *pbOutPos++ = (unsigned char)dwBitBuff;
+ cbOutSize--;
+ }
+
+ dwBitBuff >>= 8;
+ nBits -= 8;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// TInputStream functions
+
+// Gets one bit from input stream
+unsigned long TInputStream::GetBit()
+{
+ unsigned long dwOneBit = 0;
+
+ // Ensure that the input stream is reloaded, if there are no bits left
+ if(BitCount == 0)
+ {
+ // Refill the bit buffer
+ BitBuffer = *pbInBuffer++;
+ BitCount = 8;
+ }
+
+ // Copy the bit from bit buffer to the variable
+ dwOneBit = (BitBuffer & 0x01);
+ BitBuffer >>= 1;
+ BitCount--;
+
+ return dwOneBit;
+}
+
+// Gets 7 bits from the stream. DOES NOT remove the bits from input stream
+unsigned long TInputStream::Get7Bits()
+{
+ unsigned long dwReloadByte = 0;
+
+ // If there is not enough bits to get the value,
+ // we have to add 8 more bits from the input buffer
+ if(BitCount < 7)
+ {
+ dwReloadByte = *pbInBuffer++;
+ BitBuffer |= dwReloadByte << BitCount;
+ BitCount += 8;
+ }
+
+ // Return the first available 7 bits. DO NOT remove them from the input stream
+ return (BitBuffer & 0x7F);
+}
+
+// Gets the whole byte from the input stream.
+unsigned long TInputStream::Get8Bits()
+{
+ unsigned long dwReloadByte = 0;
+ unsigned long dwOneByte = 0;
+
+ // If there is not enough bits to get the value,
+ // we have to add 8 more bits from the input buffer
+ if(BitCount < 8)
+ {
+ dwReloadByte = *pbInBuffer++;
+ BitBuffer |= dwReloadByte << BitCount;
+ BitCount += 8;
+ }
+
+ // Return the lowest 8 its
+ dwOneByte = (BitBuffer & 0xFF);
+ BitBuffer >>= 8;
+ BitCount -= 8;
+ return dwOneByte;
+}
+
+void TInputStream::SkipBits(unsigned int dwBitsToSkip)
+{
+ unsigned long dwReloadByte = 0;
+
+ // If there is not enough bits in the buffer,
+ // we have to add 8 more bits from the input buffer
+ if(BitCount < dwBitsToSkip)
+ {
+ dwReloadByte = *pbInBuffer++;
+ BitBuffer |= dwReloadByte << BitCount;
+ BitCount += 8;
+ }
+
+ // Skip the remaining bits
+ BitBuffer >>= dwBitsToSkip;
+ BitCount -= dwBitsToSkip;
+}
+
+//-----------------------------------------------------------------------------
+// Functions for huffmann tree items
+
+// 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))
+ {
+ if(prev != NULL)
+ {
+ prev2 = PTR_NOT(prev);
+ if(prev2 != NULL)
+ {
+ 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;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// THuffmannTree class functions
+
+THuffmannTree::THuffmannTree()
+{
+ // We have to check if the "this" pointer is less than zero
+ if((LONG_PTR)this < 0)
+ mul = -1;
+}
+
+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;
+ }
+}
+
+// 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;
+}
+/*
+// Modifies Huffman tree. Adds new item and changes
+void THuffmannTree::ModifyTree(unsigned long dwIndex)
+{
+ THTreeItem * pItem1 = pItem3058; // ESI
+ THTreeItem * pSaveLast = (PTR_INT(pLast) <= 0) ? NULL : pLast; // EBX
+ THTreeItem * temp; // EAX
+
+ // Prepare the first item to insert to the tree
+ if(PTR_INT(pItem1) <= 0)
+ pItem1 = &items0008[nItems++];
+
+ // If item has any next item, remove it from the chain
+ if(pItem1->next != NULL)
+ {
+ THTreeItem * temp = pItem1->GetPrevItem(-1); // EAX
+
+ temp->next = pItem1->next;
+ pItem1->next->prev = pItem1->prev;
+ pItem1->next = NULL;
+ pItem1->prev = NULL;
+ }
+
+ pItem1->next = PTR_PTR(&pFirst);
+ pItem1->prev = pLast;
+ temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C));
+
+ // 150068E9
+ temp->next = pItem1;
+ pLast = pItem1;
+
+ pItem1->parent = NULL;
+ pItem1->child = NULL;
+
+ // 150068F6
+ pItem1->dcmpByte = pSaveLast->dcmpByte; // Copy item index
+ pItem1->byteValue = pSaveLast->byteValue; // Copy item byte value
+ pItem1->parent = pSaveLast; // Set parent to last item
+ items306C[pSaveLast->dcmpByte] = pItem1; // Insert item into item pointer array
+
+ // Prepare the second item to insert into the tree
+ if(PTR_INT((pItem1 = pItem3058)) <= 0)
+ pItem1 = &items0008[nItems++];
+
+ // 1500692E
+ if(pItem1->next != NULL)
+ {
+ temp = pItem1->GetPrevItem(-1); // EAX
+
+ temp->next = pItem1->next;
+ pItem1->next->prev = pItem1->prev;
+ pItem1->next = NULL;
+ pItem1->prev = NULL;
+ }
+ // 1500694C
+ pItem1->next = PTR_PTR(&pFirst);
+ pItem1->prev = pLast;
+ temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C));
+
+ // 15006968
+ temp->next = pItem1;
+ pLast = pItem1;
+
+ // 1500696E
+ pItem1->child = NULL;
+ pItem1->dcmpByte = dwIndex;
+ pItem1->byteValue = 0;
+ pItem1->parent = pSaveLast;
+ pSaveLast->child = pItem1;
+ items306C[dwIndex] = pItem1;
+
+ do
+ {
+ THTreeItem * pItem2 = pItem1;
+ THTreeItem * pItem3;
+ unsigned long byteValue;
+
+ // 15006993
+ byteValue = ++pItem1->byteValue;
+
+ // Pass through all previous which have its value greater than byteValue
+ while(PTR_INT((pItem3 = pItem2->prev)) > 0) // EBX
+ {
+ if(pItem3->byteValue >= byteValue)
+ goto _150069AE;
+
+ pItem2 = pItem2->prev;
+ }
+ // 150069AC
+ pItem3 = NULL;
+
+ _150069AE:
+ if(pItem2 == pItem1)
+ continue;
+
+ // 150069B2
+ // Switch pItem2 with item
+ InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1);
+ InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3);
+
+ // 150069D0
+ // Switch parents of pItem1 and pItem2
+ temp = pItem2->parent->child;
+ if(pItem1 == pItem1->parent->child)
+ pItem1->parent->child = pItem2;
+
+ if(pItem2 == temp)
+ pItem2->parent->child = pItem1;
+
+ // 150069ED
+ // Switch parents of pItem1 and pItem3
+ temp = pItem1->parent;
+ pItem1 ->parent = pItem2->parent;
+ pItem2->parent = temp;
+ offs0004++;
+ }
+ while(PTR_INT((pItem1 = pItem1->parent)) > 0);
+}
+
+void THuffmannTree::UninitTree()
+{
+ while(PTR_INT(pLast) > 0)
+ {
+ pItem = pItem305C->Call1501DB70(pLast);
+ pItem->RemoveItem();
+ }
+
+ for(pItem = pFirst; PTR_INT(pItem3058) > 0; pItem = pItem3058)
+ pItem->RemoveItem();
+ PTR_PTR(&pItem3054)->RemoveItem();
+
+ for(pItem = items0008 + 0x203, nCount = 0x203; nCount != 0; nCount--)
+ {
+ pItem--;
+ pItem->RemoveItem();
+ pItem->RemoveItem();
+ }
+}
+*/
+
+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_OR_NULL(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_OR_NULL(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 += PTR_INT(pItem305C);
+
+ pPrev->next = pItem1;
+ ppItem[1] = pItem2;
+ pItem2->parent = NULL;
+ pItem2->child = NULL;
+ }
+ }
+ return pItem2;
+}
+
+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++;
+ }
+}
+
+// 1500E920
+unsigned int THuffmannTree::DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType)
+{
+ THTreeItem * pItem1;
+ THTreeItem * pItem2;
+ THTreeItem * pItem3;
+ THTreeItem * pTemp;
+ unsigned long dwBitBuff;
+ unsigned int nBits;
+ unsigned int nBit;
+
+ BuildTree(nCmpType);
+ bIsCmp0 = (nCmpType == 0);
+
+ // Store the compression type into output buffer
+ os->dwBitBuff |= (nCmpType << os->nBits);
+ os->nBits += 8;
+
+ // Flush completed bytes
+ while(os->nBits >= 8)
+ {
+ if(os->cbOutSize != 0)
+ {
+ *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
+ os->cbOutSize--;
+ }
+
+ os->dwBitBuff >>= 8;
+ os->nBits -= 8;
+ }
+
+ for(; nInLength != 0; nInLength--)
+ {
+ unsigned char bOneByte = *pbInBuffer++;
+
+ if((pItem1 = items306C[bOneByte]) == NULL)
+ {
+ pItem2 = items306C[0x101]; // ecx
+ pItem3 = pItem2->parent; // eax
+ dwBitBuff = 0;
+ nBits = 0;
+
+ for(; pItem3 != NULL; pItem3 = pItem3->parent)
+ {
+ nBit = (pItem3->child != pItem2) ? 1 : 0;
+ dwBitBuff = (dwBitBuff << 1) | nBit;
+ nBits++;
+ pItem2 = pItem3;
+ }
+ os->PutBits(dwBitBuff, nBits);
+
+ // Store the loaded byte into output stream
+ os->dwBitBuff |= (bOneByte << os->nBits);
+ os->nBits += 8;
+
+ // Flush the whole byte(s)
+ while(os->nBits >= 8)
+ {
+ if(os->cbOutSize != 0)
+ {
+ *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
+ os->cbOutSize--;
+ }
+ os->dwBitBuff >>= 8;
+ os->nBits -= 8;
+ }
+
+ pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast;
+ pItem2 = Call1500E740(1);
+ pItem2->dcmpByte = pItem1->dcmpByte;
+ pItem2->byteValue = pItem1->byteValue;
+ pItem2->parent = pItem1;
+ items306C[pItem2->dcmpByte] = pItem2;
+
+ pItem2 = Call1500E740(1);
+ pItem2->dcmpByte = bOneByte;
+ pItem2->byteValue = 0;
+ pItem2->parent = pItem1;
+ items306C[pItem2->dcmpByte] = pItem2;
+ pItem1->child = pItem2;
+
+ Call1500E820(pItem2);
+
+ if(bIsCmp0 != 0)
+ {
+ Call1500E820(items306C[bOneByte]);
+ continue;
+ }
+
+ for(pItem1 = items306C[bOneByte]; pItem1 != NULL; pItem1 = pItem1->parent)
+ {
+ pItem1->byteValue++;
+ pItem2 = pItem1;
+
+ for(;;)
+ {
+ pItem3 = pItem2->prev;
+ if(PTR_INVALID_OR_NULL(pItem3))
+ {
+ pItem3 = NULL;
+ break;
+ }
+ if(pItem3->byteValue >= pItem1->byteValue)
+ break;
+ pItem2 = pItem3;
+ }
+
+ if(pItem2 != pItem1)
+ {
+ InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1);
+ InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3);
+
+ pItem3 = pItem2->parent->child;
+ if(pItem1->parent->child == pItem1)
+ pItem1->parent->child = pItem2;
+
+ if(pItem3 == pItem2)
+ pItem2->parent->child = pItem1;
+
+ pTemp = pItem1->parent;
+ pItem1->parent = pItem2->parent;
+ pItem2->parent = pTemp;
+ offs0004++;
+ }
+ }
+ }
+// 1500EB62
+ else
+ {
+ dwBitBuff = 0;
+ nBits = 0;
+ for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent)
+ {
+ nBit = (pItem2->child != pItem1) ? 1 : 0;
+ dwBitBuff = (dwBitBuff << 1) | nBit;
+ nBits++;
+ pItem1 = pItem2;
+ }
+ os->PutBits(dwBitBuff, nBits);
+ }
+
+// 1500EB98
+ if(bIsCmp0 != 0)
+ Call1500E820(items306C[bOneByte]); // 1500EB9D
+// 1500EBAF
+ } // for(; nInLength != 0; nInLength--)
+
+// 1500EBB8
+ pItem1 = items306C[0x100];
+ dwBitBuff = 0;
+ nBits = 0;
+ for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent)
+ {
+ nBit = (pItem2->child != pItem1) ? 1 : 0;
+ dwBitBuff = (dwBitBuff << 1) | nBit;
+ nBits++;
+ pItem1 = pItem2;
+ }
+
+// 1500EBE6
+ os->PutBits(dwBitBuff, nBits);
+
+// 1500EBEF
+ // Flush the remaining bits
+ while(os->nBits != 0)
+ {
+ if(os->cbOutSize != 0)
+ {
+ *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
+ os->cbOutSize--;
+ }
+ os->dwBitBuff >>= 8;
+ os->nBits -= ((os->nBits > 8) ? 8 : os->nBits);
+ }
+
+ return (unsigned int)(os->pbOutPos - os->pbOutBuffer);
+}
+
+// Decompression using Huffman tree (1500E450)
+unsigned int THuffmannTree::DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is)
+{
+ TQDecompress * qd;
+ THTreeItem * pItem1;
+ THTreeItem * pItem2;
+ unsigned char * pbOutPos = pbOutBuffer;
+ unsigned long nBitCount;
+ unsigned int nDcmpByte = 0;
+ unsigned int n8Bits; // 8 bits loaded from input stream
+ unsigned int n7Bits; // 7 bits loaded from input stream
+ bool bHasQdEntry;
+
+ // Test the output length. Must not be NULL.
+ if(dwOutLength == 0)
+ return 0;
+
+ // Get the compression type from the input stream
+ n8Bits = is->Get8Bits();
+
+ // Build the Huffman tree
+ BuildTree(n8Bits);
+ bIsCmp0 = (n8Bits == 0) ? 1 : 0;
+
+ for(;;)
+ {
+ // Security check: If we are at the end of the input buffer,
+ // it means that the data is corrupt
+ if(is->BitCount == 0 && is->pbInBuffer >= is->pbInBufferEnd)
+ return 0;
+
+ // Get 7 bits from input stream
+ n7Bits = is->Get7Bits();
+
+ // Try to use quick decompression. Check TQDecompress array for corresponding item.
+ // If found, ise the result byte instead.
+ qd = &qd3474[n7Bits];
+
+ // If there is a quick-pass possible (ebx)
+ bHasQdEntry = (qd->offs00 >= offs0004) ? true : false;
+
+ // If we can use quick decompress, use it.
+ if(bHasQdEntry)
+ {
+ if(qd->nBits > 7)
+ {
+ is->SkipBits(7);
+ pItem1 = qd->pItem;
+ goto _1500E549;
+ }
+ is->SkipBits(qd->nBits);
+ nDcmpByte = qd->dcmpByte;
+ }
+ else
+ {
+ pItem1 = pFirst->next->prev;
+ if(PTR_INVALID_OR_NULL(pItem1))
+ pItem1 = NULL;
+_1500E549:
+ nBitCount = 0;
+ pItem2 = NULL;
+
+ do
+ {
+ if(pItem1 == NULL)
+ return 0;
+
+ pItem1 = pItem1->child; // Move down by one level
+ if(is->GetBit()) // If current bit is set, move to previous
+ pItem1 = pItem1->prev;
+
+ if(++nBitCount == 7) // If we are at 7th bit, save current HTree item.
+ pItem2 = pItem1;
+ }
+ while(pItem1->child != NULL); // Walk until tree has no deeper level
+
+ if(bHasQdEntry == false)
+ {
+ if(nBitCount > 7)
+ {
+ qd->offs00 = offs0004;
+ qd->nBits = nBitCount;
+ qd->pItem = pItem2;
+ }
+ else
+ {
+ unsigned long nIndex = n7Bits & (0xFFFFFFFF >> (32 - nBitCount));
+ unsigned long nAdd = (1 << nBitCount);
+
+ for(qd = &qd3474[nIndex]; nIndex <= 0x7F; nIndex += nAdd, qd += nAdd)
+ {
+ qd->offs00 = offs0004;
+ qd->nBits = nBitCount;
+ qd->dcmpByte = pItem1->dcmpByte;
+ }
+ }
+ }
+ nDcmpByte = pItem1->dcmpByte;
+ }
+
+ if(nDcmpByte == 0x101) // Huffman tree needs to be modified
+ {
+ n8Bits = is->Get8Bits();
+ pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast;
+
+ pItem2 = Call1500E740(1);
+ pItem2->parent = pItem1;
+ pItem2->dcmpByte = pItem1->dcmpByte;
+ pItem2->byteValue = pItem1->byteValue;
+ items306C[pItem2->dcmpByte] = pItem2;
+
+ pItem2 = Call1500E740(1);
+ pItem2->parent = pItem1;
+ pItem2->dcmpByte = n8Bits;
+ pItem2->byteValue = 0;
+ items306C[pItem2->dcmpByte] = pItem2;
+
+ pItem1->child = pItem2;
+ Call1500E820(pItem2);
+ if(bIsCmp0 == 0)
+ Call1500E820(items306C[n8Bits]);
+
+ nDcmpByte = n8Bits;
+ }
+
+ if(nDcmpByte == 0x100)
+ break;
+
+ *pbOutPos++ = (unsigned char)nDcmpByte;
+ if(--dwOutLength == 0)
+ break;
+
+ if(bIsCmp0)
+ Call1500E820(items306C[nDcmpByte]);
+ }
+
+ return (unsigned int)(pbOutPos - pbOutBuffer);
+}
+
+
+// Table for (de)compression. Every compression type has 258 entries
+unsigned char THuffmannTree::Table1502A630[] =
+{
+ // Data for compression type 0x00
+ 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00,
+
+ // Data for compression type 0x01
+ 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05,
+ 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02,
+ 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02,
+ 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04,
+ 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02,
+ 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02,
+ 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03,
+ 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03,
+ 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
+ 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B,
+ 0x00, 0x00,
+
+ // Data for compression type 0x02
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04,
+ 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01,
+ 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02,
+ 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01,
+ 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A,
+ 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ // Data for compression type 0x03
+ 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03,
+ 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
+ 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01,
+ 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03,
+ 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03,
+ 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01,
+ 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
+ 0x00, 0x00,
+
+ // Data for compression type 0x04
+ 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ // Data for compression type 0x05
+ 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82,
+ 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37,
+ 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D,
+ 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ // Data for compression type 0x06
+ 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ // Data for compression type 0x07
+ 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ // Data for compression type 0x08
+ 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10,
+ 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11,
+ 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00
+};