|
@@ -29,233 +29,231 @@
|
|
|
|
|
|
#include "common.h"
|
|
|
|
|
|
-#ifndef PAL_WIN95
|
|
|
-
|
|
|
-typedef struct _TreeNode
|
|
|
+typedef struct _YJ1_TreeNode
|
|
|
{
|
|
|
- unsigned char value;
|
|
|
- unsigned char leaf;
|
|
|
- unsigned short level;
|
|
|
- unsigned int weight;
|
|
|
+ unsigned char value;
|
|
|
+ unsigned char leaf;
|
|
|
+ unsigned short level;
|
|
|
+ unsigned int weight;
|
|
|
|
|
|
- struct _TreeNode *parent;
|
|
|
- struct _TreeNode *left;
|
|
|
- struct _TreeNode *right;
|
|
|
-} TreeNode;
|
|
|
+ struct _YJ1_TreeNode *parent;
|
|
|
+ struct _YJ1_TreeNode *left;
|
|
|
+ struct _YJ1_TreeNode *right;
|
|
|
+} YJ1_TreeNode;
|
|
|
|
|
|
-typedef struct _TreeNodeList
|
|
|
+typedef struct _YJ1_TreeNodeList
|
|
|
{
|
|
|
- TreeNode *node;
|
|
|
- struct _TreeNodeList *next;
|
|
|
-} TreeNodeList;
|
|
|
+ YJ1_TreeNode *node;
|
|
|
+ struct _YJ1_TreeNodeList *next;
|
|
|
+} YJ1_TreeNodeList;
|
|
|
|
|
|
typedef struct _YJ_1_FILEHEADER
|
|
|
{
|
|
|
- unsigned int Signature;
|
|
|
- unsigned int UncompressedLength;
|
|
|
- unsigned int CompressedLength;
|
|
|
- unsigned short BlockCount;
|
|
|
- unsigned char Unknown;
|
|
|
- unsigned char HuffmanTreeLength;
|
|
|
+ unsigned int Signature;
|
|
|
+ unsigned int UncompressedLength;
|
|
|
+ unsigned int CompressedLength;
|
|
|
+ unsigned short BlockCount;
|
|
|
+ unsigned char Unknown;
|
|
|
+ unsigned char HuffmanTreeLength;
|
|
|
} YJ_1_FILEHEADER, *PYJ_1_FILEHEADER;
|
|
|
|
|
|
typedef struct _YJ_1_BLOCKHEADER
|
|
|
{
|
|
|
- unsigned short UncompressedLength;
|
|
|
- unsigned short CompressedLength;
|
|
|
- unsigned short LZSSRepeatTable[4];
|
|
|
- unsigned char LZSSOffsetCodeLengthTable[4];
|
|
|
- unsigned char LZSSRepeatCodeLengthTable[3];
|
|
|
- unsigned char CodeCountCodeLengthTable[3];
|
|
|
- unsigned char CodeCountTable[2];
|
|
|
+ unsigned short UncompressedLength;
|
|
|
+ unsigned short CompressedLength;
|
|
|
+ unsigned short LZSSRepeatTable[4];
|
|
|
+ unsigned char LZSSOffsetCodeLengthTable[4];
|
|
|
+ unsigned char LZSSRepeatCodeLengthTable[3];
|
|
|
+ unsigned char CodeCountCodeLengthTable[3];
|
|
|
+ unsigned char CodeCountTable[2];
|
|
|
} YJ_1_BLOCKHEADER, *PYJ_1_BLOCKHEADER;
|
|
|
|
|
|
static unsigned int
|
|
|
-get_bits(
|
|
|
- const void *src,
|
|
|
- unsigned int *bitptr,
|
|
|
- unsigned int count
|
|
|
-)
|
|
|
+ yj1_get_bits(
|
|
|
+ const void *src,
|
|
|
+ unsigned int *bitptr,
|
|
|
+ unsigned int count
|
|
|
+ )
|
|
|
{
|
|
|
- unsigned char *temp = ((unsigned char *)src) + ((*bitptr >> 4) << 1);
|
|
|
- unsigned int bptr = *bitptr & 0xf;
|
|
|
- unsigned short mask;
|
|
|
- *bitptr += count;
|
|
|
- if (count > 16 - bptr)
|
|
|
- {
|
|
|
- count = count + bptr - 16;
|
|
|
- mask = 0xffff >> bptr;
|
|
|
- return (((temp[0] | (temp[1] << 8)) & mask) << count) | ((temp[2] | (temp[3] << 8)) >> (16 - count));
|
|
|
- }
|
|
|
- else
|
|
|
- return (((unsigned short)((temp[0] | (temp[1] << 8)) << bptr)) >> (16 - count));
|
|
|
+ unsigned char *temp = ((unsigned char *)src) + ((*bitptr >> 4) << 1);
|
|
|
+ unsigned int bptr = *bitptr & 0xf;
|
|
|
+ unsigned short mask;
|
|
|
+ *bitptr += count;
|
|
|
+ if (count > 16 - bptr)
|
|
|
+ {
|
|
|
+ count = count + bptr - 16;
|
|
|
+ mask = 0xffff >> bptr;
|
|
|
+ return (((temp[0] | (temp[1] << 8)) & mask) << count) | ((temp[2] | (temp[3] << 8)) >> (16 - count));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return (((unsigned short)((temp[0] | (temp[1] << 8)) << bptr)) >> (16 - count));
|
|
|
}
|
|
|
|
|
|
static unsigned short
|
|
|
-get_loop(
|
|
|
- const void *src,
|
|
|
- unsigned int *bitptr,
|
|
|
- PYJ_1_BLOCKHEADER header
|
|
|
-)
|
|
|
+ yj1_get_loop(
|
|
|
+ const void *src,
|
|
|
+ unsigned int *bitptr,
|
|
|
+ PYJ_1_BLOCKHEADER header
|
|
|
+ )
|
|
|
{
|
|
|
- if (get_bits(src, bitptr, 1))
|
|
|
- return header->CodeCountTable[0];
|
|
|
- else
|
|
|
- {
|
|
|
- unsigned int temp = get_bits(src, bitptr, 2);
|
|
|
- if (temp)
|
|
|
- return get_bits(src, bitptr, header->CodeCountCodeLengthTable[temp - 1]);
|
|
|
- else
|
|
|
- return header->CodeCountTable[1];
|
|
|
- }
|
|
|
+ if (yj1_get_bits(src, bitptr, 1))
|
|
|
+ return header->CodeCountTable[0];
|
|
|
+ else
|
|
|
+ {
|
|
|
+ unsigned int temp = yj1_get_bits(src, bitptr, 2);
|
|
|
+ if (temp)
|
|
|
+ return yj1_get_bits(src, bitptr, header->CodeCountCodeLengthTable[temp - 1]);
|
|
|
+ else
|
|
|
+ return header->CodeCountTable[1];
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static unsigned short
|
|
|
-get_count(
|
|
|
- const void *src,
|
|
|
- unsigned int *bitptr,
|
|
|
- PYJ_1_BLOCKHEADER header
|
|
|
-)
|
|
|
+ yj1_get_count(
|
|
|
+ const void *src,
|
|
|
+ unsigned int *bitptr,
|
|
|
+ PYJ_1_BLOCKHEADER header
|
|
|
+ )
|
|
|
{
|
|
|
- unsigned short temp;
|
|
|
- if ((temp = get_bits(src, bitptr, 2)) != 0)
|
|
|
- {
|
|
|
- if (get_bits(src, bitptr, 1))
|
|
|
- return get_bits(src, bitptr, header->LZSSRepeatCodeLengthTable[temp - 1]);
|
|
|
- else
|
|
|
- return SWAP16(header->LZSSRepeatTable[temp]);
|
|
|
- }
|
|
|
- else
|
|
|
- return SWAP16(header->LZSSRepeatTable[0]);
|
|
|
+ unsigned short temp;
|
|
|
+ if ((temp = yj1_get_bits(src, bitptr, 2)) != 0)
|
|
|
+ {
|
|
|
+ if (yj1_get_bits(src, bitptr, 1))
|
|
|
+ return yj1_get_bits(src, bitptr, header->LZSSRepeatCodeLengthTable[temp - 1]);
|
|
|
+ else
|
|
|
+ return SWAP16(header->LZSSRepeatTable[temp]);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return SWAP16(header->LZSSRepeatTable[0]);
|
|
|
}
|
|
|
|
|
|
INT
|
|
|
-Decompress(
|
|
|
- LPCVOID Source,
|
|
|
- LPVOID Destination,
|
|
|
- INT DestSize
|
|
|
-)
|
|
|
+ YJ1_Decompress(
|
|
|
+ LPCVOID Source,
|
|
|
+ LPVOID Destination,
|
|
|
+ INT DestSize
|
|
|
+ )
|
|
|
{
|
|
|
- PYJ_1_FILEHEADER hdr = (PYJ_1_FILEHEADER)Source;
|
|
|
- unsigned char *src = (unsigned char *)Source;
|
|
|
- unsigned char *dest;
|
|
|
- unsigned int i;
|
|
|
- TreeNode *root, *node;
|
|
|
-
|
|
|
- if (Source == NULL)
|
|
|
- return -1;
|
|
|
- if (SWAP32(hdr->Signature) != 0x315f4a59)
|
|
|
- return -1;
|
|
|
- if (SWAP32(hdr->UncompressedLength) > (unsigned int)DestSize)
|
|
|
- return -1;
|
|
|
-
|
|
|
- do
|
|
|
- {
|
|
|
- unsigned short tree_len = ((unsigned short)hdr->HuffmanTreeLength) * 2;
|
|
|
- unsigned int bitptr = 0;
|
|
|
- unsigned char *flag = (unsigned char *)src + 16 + tree_len;
|
|
|
-
|
|
|
- if ((node = root = (TreeNode *)malloc(sizeof(TreeNode) * (tree_len + 1))) == NULL)
|
|
|
- return -1;
|
|
|
- root[0].leaf = 0;
|
|
|
- root[0].value = 0;
|
|
|
- root[0].left = root + 1;
|
|
|
- root[0].right = root + 2;
|
|
|
- for (i = 1; i <= tree_len; i++)
|
|
|
- {
|
|
|
- root[i].leaf = !get_bits(flag, &bitptr, 1);
|
|
|
- root[i].value = src[15 + i];
|
|
|
- if (root[i].leaf)
|
|
|
- root[i].left = root[i].right = NULL;
|
|
|
- else
|
|
|
- {
|
|
|
- root[i].left = root + (root[i].value << 1) + 1;
|
|
|
- root[i].right = root[i].left + 1;
|
|
|
- }
|
|
|
- }
|
|
|
- src += 16 + tree_len + (((tree_len & 0xf) ? (tree_len >> 4) + 1 : (tree_len >> 4)) << 1);
|
|
|
- } while (0);
|
|
|
-
|
|
|
- dest = (unsigned char *)Destination;
|
|
|
-
|
|
|
- for (i = 0; i < SWAP16(hdr->BlockCount); i++)
|
|
|
- {
|
|
|
- unsigned int bitptr;
|
|
|
- PYJ_1_BLOCKHEADER header;
|
|
|
-
|
|
|
- header = (PYJ_1_BLOCKHEADER)src;
|
|
|
- src += 4;
|
|
|
- if (!SWAP16(header->CompressedLength))
|
|
|
- {
|
|
|
- unsigned short hul = SWAP16(header->UncompressedLength);
|
|
|
- while (hul--)
|
|
|
- {
|
|
|
- *dest++ = *src++;
|
|
|
- }
|
|
|
- continue;
|
|
|
- }
|
|
|
- src += 20;
|
|
|
- bitptr = 0;
|
|
|
- for (;;)
|
|
|
- {
|
|
|
- unsigned short loop;
|
|
|
- if ((loop = get_loop(src, &bitptr, header)) == 0)
|
|
|
- break;
|
|
|
-
|
|
|
- while (loop--)
|
|
|
- {
|
|
|
- node = root;
|
|
|
- for(; !node->leaf;)
|
|
|
- {
|
|
|
- if (get_bits(src, &bitptr, 1))
|
|
|
- node = node->right;
|
|
|
- else
|
|
|
- node = node->left;
|
|
|
- }
|
|
|
- *dest++ = node->value;
|
|
|
- }
|
|
|
-
|
|
|
- if ((loop = get_loop(src, &bitptr, header)) == 0)
|
|
|
- break;
|
|
|
-
|
|
|
- while (loop--)
|
|
|
- {
|
|
|
- unsigned int pos, count;
|
|
|
- count = get_count(src, &bitptr, header);
|
|
|
- pos = get_bits(src, &bitptr, 2);
|
|
|
- pos = get_bits(src, &bitptr, header->LZSSOffsetCodeLengthTable[pos]);
|
|
|
- while (count--)
|
|
|
- {
|
|
|
- *dest = *(dest - pos);
|
|
|
- dest++;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- src = ((unsigned char *)header) + SWAP16(header->CompressedLength);
|
|
|
- }
|
|
|
- free(root);
|
|
|
-
|
|
|
- return SWAP32(hdr->UncompressedLength);
|
|
|
+ PYJ_1_FILEHEADER hdr = (PYJ_1_FILEHEADER)Source;
|
|
|
+ unsigned char *src = (unsigned char *)Source;
|
|
|
+ unsigned char *dest;
|
|
|
+ unsigned int i;
|
|
|
+ YJ1_TreeNode *root, *node;
|
|
|
+
|
|
|
+ if (Source == NULL)
|
|
|
+ return -1;
|
|
|
+ if (SWAP32(hdr->Signature) != 0x315f4a59)
|
|
|
+ return -1;
|
|
|
+ if (SWAP32(hdr->UncompressedLength) > (unsigned int)DestSize)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ unsigned short tree_len = ((unsigned short)hdr->HuffmanTreeLength) * 2;
|
|
|
+ unsigned int bitptr = 0;
|
|
|
+ unsigned char *flag = (unsigned char *)src + 16 + tree_len;
|
|
|
+
|
|
|
+ if ((node = root = (YJ1_TreeNode *)malloc(sizeof(YJ1_TreeNode) * (tree_len + 1))) == NULL)
|
|
|
+ return -1;
|
|
|
+ root[0].leaf = 0;
|
|
|
+ root[0].value = 0;
|
|
|
+ root[0].left = root + 1;
|
|
|
+ root[0].right = root + 2;
|
|
|
+ for (i = 1; i <= tree_len; i++)
|
|
|
+ {
|
|
|
+ root[i].leaf = !yj1_get_bits(flag, &bitptr, 1);
|
|
|
+ root[i].value = src[15 + i];
|
|
|
+ if (root[i].leaf)
|
|
|
+ root[i].left = root[i].right = NULL;
|
|
|
+ else
|
|
|
+ {
|
|
|
+ root[i].left = root + (root[i].value << 1) + 1;
|
|
|
+ root[i].right = root[i].left + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ src += 16 + tree_len + (((tree_len & 0xf) ? (tree_len >> 4) + 1 : (tree_len >> 4)) << 1);
|
|
|
+ } while (0);
|
|
|
+
|
|
|
+ dest = (unsigned char *)Destination;
|
|
|
+
|
|
|
+ for (i = 0; i < SWAP16(hdr->BlockCount); i++)
|
|
|
+ {
|
|
|
+ unsigned int bitptr;
|
|
|
+ PYJ_1_BLOCKHEADER header;
|
|
|
+
|
|
|
+ header = (PYJ_1_BLOCKHEADER)src;
|
|
|
+ src += 4;
|
|
|
+ if (!SWAP16(header->CompressedLength))
|
|
|
+ {
|
|
|
+ unsigned short hul = SWAP16(header->UncompressedLength);
|
|
|
+ while (hul--)
|
|
|
+ {
|
|
|
+ *dest++ = *src++;
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ src += 20;
|
|
|
+ bitptr = 0;
|
|
|
+ for (;;)
|
|
|
+ {
|
|
|
+ unsigned short loop;
|
|
|
+ if ((loop = yj1_get_loop(src, &bitptr, header)) == 0)
|
|
|
+ break;
|
|
|
+
|
|
|
+ while (loop--)
|
|
|
+ {
|
|
|
+ node = root;
|
|
|
+ for (; !node->leaf;)
|
|
|
+ {
|
|
|
+ if (yj1_get_bits(src, &bitptr, 1))
|
|
|
+ node = node->right;
|
|
|
+ else
|
|
|
+ node = node->left;
|
|
|
+ }
|
|
|
+ *dest++ = node->value;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((loop = yj1_get_loop(src, &bitptr, header)) == 0)
|
|
|
+ break;
|
|
|
+
|
|
|
+ while (loop--)
|
|
|
+ {
|
|
|
+ unsigned int pos, count;
|
|
|
+ count = yj1_get_count(src, &bitptr, header);
|
|
|
+ pos = yj1_get_bits(src, &bitptr, 2);
|
|
|
+ pos = yj1_get_bits(src, &bitptr, header->LZSSOffsetCodeLengthTable[pos]);
|
|
|
+ while (count--)
|
|
|
+ {
|
|
|
+ *dest = *(dest - pos);
|
|
|
+ dest++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ src = ((unsigned char *)header) + SWAP16(header->CompressedLength);
|
|
|
+ }
|
|
|
+ free(root);
|
|
|
+
|
|
|
+ return SWAP32(hdr->UncompressedLength);
|
|
|
}
|
|
|
|
|
|
-#else
|
|
|
+
|
|
|
|
|
|
-typedef struct _TreeNode
|
|
|
+typedef struct _YJ2_TreeNode
|
|
|
{
|
|
|
- unsigned short weight;
|
|
|
- unsigned short value;
|
|
|
- struct _TreeNode *parent;
|
|
|
- struct _TreeNode *left;
|
|
|
- struct _TreeNode *right;
|
|
|
-} TreeNode;
|
|
|
-
|
|
|
-typedef struct _Tree
|
|
|
+ unsigned short weight;
|
|
|
+ unsigned short value;
|
|
|
+ struct _YJ2_TreeNode *parent;
|
|
|
+ struct _YJ2_TreeNode *left;
|
|
|
+ struct _YJ2_TreeNode *right;
|
|
|
+} YJ2_TreeNode;
|
|
|
+
|
|
|
+typedef struct _YJ2_Tree
|
|
|
{
|
|
|
- TreeNode *node;
|
|
|
- TreeNode **list;
|
|
|
-} Tree;
|
|
|
+ YJ2_TreeNode *node;
|
|
|
+ YJ2_TreeNode **list;
|
|
|
+} YJ2_Tree;
|
|
|
|
|
|
-static unsigned char data1[0x100] =
|
|
|
+static unsigned char yj2_data1[0x100] =
|
|
|
{
|
|
|
0x3f, 0x0b, 0x17, 0x03, 0x2f, 0x0a, 0x16, 0x00, 0x2e, 0x09, 0x15, 0x02, 0x2d, 0x01, 0x08, 0x00,
|
|
|
0x3e, 0x07, 0x14, 0x03, 0x2c, 0x06, 0x13, 0x00, 0x2b, 0x05, 0x12, 0x02, 0x2a, 0x01, 0x04, 0x00,
|
|
@@ -274,166 +272,166 @@ static unsigned char data1[0x100] =
|
|
|
0x31, 0x0b, 0x11, 0x03, 0x1d, 0x0a, 0x10, 0x00, 0x1c, 0x09, 0x0f, 0x02, 0x1b, 0x01, 0x08, 0x00,
|
|
|
0x30, 0x07, 0x0e, 0x03, 0x1a, 0x06, 0x0d, 0x00, 0x19, 0x05, 0x0c, 0x02, 0x18, 0x01, 0x04, 0x00
|
|
|
};
|
|
|
-static unsigned char data2[0x10] =
|
|
|
+static unsigned char yj2_data2[0x10] =
|
|
|
{
|
|
|
0x08, 0x05, 0x06, 0x04, 0x07, 0x05, 0x06, 0x03, 0x07, 0x05, 0x06, 0x04, 0x07, 0x04, 0x05, 0x03
|
|
|
};
|
|
|
|
|
|
-static void adjust_tree(Tree tree, unsigned short value)
|
|
|
+static void yj2_adjust_tree(YJ2_Tree tree, unsigned short value)
|
|
|
{
|
|
|
- TreeNode* node = tree.list[value];
|
|
|
- TreeNode tmp;
|
|
|
- TreeNode* tmp1;
|
|
|
- TreeNode* temp;
|
|
|
- while(node->value != 0x280)
|
|
|
- {
|
|
|
- temp = node + 1;
|
|
|
- while(node->weight == temp->weight)
|
|
|
- temp++;
|
|
|
- temp--;
|
|
|
- if (temp != node)
|
|
|
- {
|
|
|
- tmp1 = node->parent;
|
|
|
- node->parent = temp->parent;
|
|
|
- temp->parent = tmp1;
|
|
|
- if (node->value > 0x140)
|
|
|
- {
|
|
|
- node->left->parent = temp;
|
|
|
- node->right->parent = temp;
|
|
|
- }
|
|
|
- else
|
|
|
- tree.list[node->value] = temp;
|
|
|
- if (temp->value > 0x140)
|
|
|
- {
|
|
|
- temp->left->parent = node;
|
|
|
- temp->right->parent = node;
|
|
|
- }
|
|
|
- else
|
|
|
- tree.list[temp->value] = node;
|
|
|
- tmp = *node; *node = *temp; *temp = tmp;
|
|
|
- node = temp;
|
|
|
- }
|
|
|
- node->weight++;
|
|
|
- node = node->parent;
|
|
|
- }
|
|
|
- node->weight++;
|
|
|
+ YJ2_TreeNode* node = tree.list[value];
|
|
|
+ YJ2_TreeNode tmp;
|
|
|
+ YJ2_TreeNode* tmp1;
|
|
|
+ YJ2_TreeNode* temp;
|
|
|
+ while (node->value != 0x280)
|
|
|
+ {
|
|
|
+ temp = node + 1;
|
|
|
+ while (node->weight == temp->weight)
|
|
|
+ temp++;
|
|
|
+ temp--;
|
|
|
+ if (temp != node)
|
|
|
+ {
|
|
|
+ tmp1 = node->parent;
|
|
|
+ node->parent = temp->parent;
|
|
|
+ temp->parent = tmp1;
|
|
|
+ if (node->value > 0x140)
|
|
|
+ {
|
|
|
+ node->left->parent = temp;
|
|
|
+ node->right->parent = temp;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ tree.list[node->value] = temp;
|
|
|
+ if (temp->value > 0x140)
|
|
|
+ {
|
|
|
+ temp->left->parent = node;
|
|
|
+ temp->right->parent = node;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ tree.list[temp->value] = node;
|
|
|
+ tmp = *node; *node = *temp; *temp = tmp;
|
|
|
+ node = temp;
|
|
|
+ }
|
|
|
+ node->weight++;
|
|
|
+ node = node->parent;
|
|
|
+ }
|
|
|
+ node->weight++;
|
|
|
}
|
|
|
|
|
|
-static int build_tree(Tree *tree)
|
|
|
+static int yj2_build_tree(YJ2_Tree *tree)
|
|
|
{
|
|
|
- int i, ptr;
|
|
|
- TreeNode** list;
|
|
|
- TreeNode* node;
|
|
|
- if ((tree->list = list = (TreeNode **)malloc(sizeof(TreeNode*) * 321)) == NULL)
|
|
|
- return 0;
|
|
|
- if ((tree->node = node = (TreeNode *)malloc(sizeof(TreeNode) * 641)) == NULL)
|
|
|
- {
|
|
|
- free(list);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- memset(list, 0, 321 * sizeof(TreeNode*));
|
|
|
- memset(node, 0, 641 * sizeof(TreeNode));
|
|
|
- for(i = 0; i <= 0x140; i++)
|
|
|
- list[i] = node + i;
|
|
|
- for(i = 0; i <= 0x280; i++)
|
|
|
- {
|
|
|
- node[i].value = i;
|
|
|
- node[i].weight = 1;
|
|
|
- }
|
|
|
- tree->node[0x280].parent = tree->node + 0x280;
|
|
|
- for(i = 0, ptr = 0x141; ptr <= 0x280; i += 2, ptr++)
|
|
|
- {
|
|
|
- node[ptr].left = node + i;
|
|
|
- node[ptr].right = node + i + 1;
|
|
|
- node[i].parent = node[i + 1].parent = node + ptr;
|
|
|
- node[ptr].weight = node[i].weight + node[i + 1].weight;
|
|
|
- }
|
|
|
- return 1;
|
|
|
+ int i, ptr;
|
|
|
+ YJ2_TreeNode** list;
|
|
|
+ YJ2_TreeNode* node;
|
|
|
+ if ((tree->list = list = (YJ2_TreeNode **)malloc(sizeof(YJ2_TreeNode*) * 321)) == NULL)
|
|
|
+ return 0;
|
|
|
+ if ((tree->node = node = (YJ2_TreeNode *)malloc(sizeof(YJ2_TreeNode) * 641)) == NULL)
|
|
|
+ {
|
|
|
+ free(list);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ memset(list, 0, 321 * sizeof(YJ2_TreeNode*));
|
|
|
+ memset(node, 0, 641 * sizeof(YJ2_TreeNode));
|
|
|
+ for (i = 0; i <= 0x140; i++)
|
|
|
+ list[i] = node + i;
|
|
|
+ for (i = 0; i <= 0x280; i++)
|
|
|
+ {
|
|
|
+ node[i].value = i;
|
|
|
+ node[i].weight = 1;
|
|
|
+ }
|
|
|
+ tree->node[0x280].parent = tree->node + 0x280;
|
|
|
+ for (i = 0, ptr = 0x141; ptr <= 0x280; i += 2, ptr++)
|
|
|
+ {
|
|
|
+ node[ptr].left = node + i;
|
|
|
+ node[ptr].right = node + i + 1;
|
|
|
+ node[i].parent = node[i + 1].parent = node + ptr;
|
|
|
+ node[ptr].weight = node[i].weight + node[i + 1].weight;
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
-static int bt(const char* data, unsigned int pos)
|
|
|
+static int yj2_bt(const char* data, unsigned int pos)
|
|
|
{
|
|
|
- return (data[pos >> 3] & (unsigned char)(1 << (pos & 0x7))) >> (pos & 0x7);
|
|
|
+ return (data[pos >> 3] & (unsigned char)(1 << (pos & 0x7))) >> (pos & 0x7);
|
|
|
}
|
|
|
|
|
|
|
|
|
INT
|
|
|
-Decompress(
|
|
|
- LPCVOID Source,
|
|
|
- LPVOID Destination,
|
|
|
- INT DestSize
|
|
|
-)
|
|
|
+ YJ2_Decompress(
|
|
|
+ LPCVOID Source,
|
|
|
+ LPVOID Destination,
|
|
|
+ INT DestSize
|
|
|
+ )
|
|
|
{
|
|
|
- int Length;
|
|
|
- unsigned int len = 0, ptr = 0;
|
|
|
- unsigned char* src = (unsigned char*)Source + 4;
|
|
|
- unsigned char* dest;
|
|
|
- Tree tree;
|
|
|
- TreeNode* node;
|
|
|
-
|
|
|
- if (Source == NULL)
|
|
|
- return -1;
|
|
|
-
|
|
|
- if (!build_tree(&tree))
|
|
|
- return -1;
|
|
|
-
|
|
|
- Length = SWAP32(*((unsigned int*)Source));
|
|
|
- if (Length > DestSize)
|
|
|
- return -1;
|
|
|
- dest = (unsigned char*)Destination;
|
|
|
-
|
|
|
- while (1)
|
|
|
- {
|
|
|
- unsigned short val;
|
|
|
- node = tree.node + 0x280;
|
|
|
- while(node->value > 0x140)
|
|
|
- {
|
|
|
- if (bt(src, ptr))
|
|
|
- node = node->right;
|
|
|
- else
|
|
|
- node = node->left;
|
|
|
- ptr++;
|
|
|
- }
|
|
|
- val = node->value;
|
|
|
- if (tree.node[0x280].weight == 0x8000)
|
|
|
- {
|
|
|
- int i;
|
|
|
- for(i = 0; i < 0x141; i++)
|
|
|
- if (tree.list[i]->weight & 0x1)
|
|
|
- adjust_tree(tree, i);
|
|
|
- for(i = 0; i <= 0x280; i++)
|
|
|
- tree.node[i].weight >>= 1;
|
|
|
- }
|
|
|
- adjust_tree(tree, val);
|
|
|
- if (val > 0xff)
|
|
|
- {
|
|
|
- int i;
|
|
|
- unsigned int temp, tmp, pos;
|
|
|
- unsigned char* pre;
|
|
|
- for(i = 0, temp = 0; i < 8; i++, ptr++)
|
|
|
- temp |= (unsigned int)bt(src, ptr) << i;
|
|
|
- tmp = temp & 0xff;
|
|
|
- for(; i < data2[tmp & 0xf] + 6; i++, ptr++)
|
|
|
- temp |= (unsigned int)bt(src, ptr) << i;
|
|
|
- temp >>= data2[tmp & 0xf];
|
|
|
- pos = (temp & 0x3f) | ((unsigned int)data1[tmp] << 6);
|
|
|
- if (pos == 0xfff)
|
|
|
- break;
|
|
|
- pre = dest - pos - 1;
|
|
|
- for(i = 0; i < val - 0xfd; i++)
|
|
|
- *dest++ = *pre++;
|
|
|
- len += val - 0xfd;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- *dest++ = (unsigned char)val;
|
|
|
- len++;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- free(tree.list);
|
|
|
- free(tree.node);
|
|
|
- return Length;
|
|
|
+ int Length;
|
|
|
+ unsigned int len = 0, ptr = 0;
|
|
|
+ unsigned char* src = (unsigned char*)Source + 4;
|
|
|
+ unsigned char* dest;
|
|
|
+ YJ2_Tree tree;
|
|
|
+ YJ2_TreeNode* node;
|
|
|
+
|
|
|
+ if (Source == NULL)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ if (!yj2_build_tree(&tree))
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ Length = SWAP32(*((unsigned int*)Source));
|
|
|
+ if (Length > DestSize)
|
|
|
+ return -1;
|
|
|
+ dest = (unsigned char*)Destination;
|
|
|
+
|
|
|
+ while (1)
|
|
|
+ {
|
|
|
+ unsigned short val;
|
|
|
+ node = tree.node + 0x280;
|
|
|
+ while (node->value > 0x140)
|
|
|
+ {
|
|
|
+ if (yj2_bt(src, ptr))
|
|
|
+ node = node->right;
|
|
|
+ else
|
|
|
+ node = node->left;
|
|
|
+ ptr++;
|
|
|
+ }
|
|
|
+ val = node->value;
|
|
|
+ if (tree.node[0x280].weight == 0x8000)
|
|
|
+ {
|
|
|
+ int i;
|
|
|
+ for (i = 0; i < 0x141; i++)
|
|
|
+ if (tree.list[i]->weight & 0x1)
|
|
|
+ yj2_adjust_tree(tree, i);
|
|
|
+ for (i = 0; i <= 0x280; i++)
|
|
|
+ tree.node[i].weight >>= 1;
|
|
|
+ }
|
|
|
+ yj2_adjust_tree(tree, val);
|
|
|
+ if (val > 0xff)
|
|
|
+ {
|
|
|
+ int i;
|
|
|
+ unsigned int temp, tmp, pos;
|
|
|
+ unsigned char* pre;
|
|
|
+ for (i = 0, temp = 0; i < 8; i++, ptr++)
|
|
|
+ temp |= (unsigned int)yj2_bt(src, ptr) << i;
|
|
|
+ tmp = temp & 0xff;
|
|
|
+ for (; i < yj2_data2[tmp & 0xf] + 6; i++, ptr++)
|
|
|
+ temp |= (unsigned int)yj2_bt(src, ptr) << i;
|
|
|
+ temp >>= yj2_data2[tmp & 0xf];
|
|
|
+ pos = (temp & 0x3f) | ((unsigned int)yj2_data1[tmp] << 6);
|
|
|
+ if (pos == 0xfff)
|
|
|
+ break;
|
|
|
+ pre = dest - pos - 1;
|
|
|
+ for (i = 0; i < val - 0xfd; i++)
|
|
|
+ *dest++ = *pre++;
|
|
|
+ len += val - 0xfd;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ *dest++ = (unsigned char)val;
|
|
|
+ len++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ free(tree.list);
|
|
|
+ free(tree.node);
|
|
|
+ return Length;
|
|
|
}
|
|
|
|
|
|
-#endif
|
|
|
+INT (*Decompress)(LPCVOID, LPVOID, INT);
|