📄 unrarlib.c
字号:
{
UnpPtr &= MAXWINMASK;
if (InAddr > sizeof (InBuf) - 30)
UnpReadBuf (0);
if (((WrPtr - UnpPtr) & MAXWINMASK) < 270 && WrPtr != UnpPtr)
{
if (FileFound)
{
if (UnpPtr < WrPtr)
{
if ((*temp_output_buffer_offset + UnpPtr) > NewLhd.UnpSize)
{
debug_log ("Fatal! Buffer overrun during decompression!");
DestUnpSize = -1;
}
else
{
/* copy extracted data to output buffer */
memcpy (temp_output_buffer + *temp_output_buffer_offset,
&UnpBuf[WrPtr], (0 - WrPtr) & MAXWINMASK);
/* update offset within buffer */
*temp_output_buffer_offset += (0 - WrPtr) & MAXWINMASK;
/* copy extracted data to output buffer */
memcpy (temp_output_buffer + *temp_output_buffer_offset,
UnpBuf, UnpPtr);
/* update offset within buffer */
*temp_output_buffer_offset += UnpPtr;
}
}
else
{
if ((*temp_output_buffer_offset + (UnpPtr - WrPtr)) >
NewLhd.UnpSize)
{
debug_log ("Fatal! Buffer overrun during decompression!");
DestUnpSize = -1;
}
else
{
/* copy extracted data to output buffer */
memcpy (temp_output_buffer + *temp_output_buffer_offset,
&UnpBuf[WrPtr], UnpPtr - WrPtr);
*temp_output_buffer_offset += UnpPtr - WrPtr; /* update offset within buffer */
}
}
}
WrPtr = UnpPtr;
}
if (UnpAudioBlock)
{
DecodeNumber ((struct Decode *) MDPtr[CurChannel]);
if (Number == 256)
{
ReadTables ();
continue;
}
UnpBuf[UnpPtr++] = DecodeAudio (Number);
if (++CurChannel == UnpChannels)
CurChannel = 0;
DestUnpSize--;
continue;
}
DecodeNumber (LitDecode2Decode (&LD));
if (Number < 256)
{
UnpBuf[UnpPtr++] = (UBYTE) Number;
DestUnpSize--;
continue;
}
if (Number > 269)
{
Length = LDecode[Number -= 270] + 3;
if ((Bits = LBits[Number]) > 0)
{
GetBits ();
Length += BitField >> (16 - Bits);
AddBits (Bits);
}
DecodeNumber (DistDecode2Decode (&DD));
Distance = DDecode[Number] + 1;
if ((Bits = DBits[Number]) > 0)
{
GetBits ();
Distance += BitField >> (16 - Bits);
AddBits (Bits);
}
if (Distance >= 0x40000L)
Length++;
if (Distance >= 0x2000)
Length++;
LastDist = OldDist[OldDistPtr++ & 3] = Distance;
DestUnpSize -= (LastLength = Length);
while (Length--)
{
UnpBuf[UnpPtr] = UnpBuf[(UnpPtr - Distance) & MAXWINMASK];
UnpPtr = (UnpPtr + 1) & MAXWINMASK;
}
continue;
}
if (Number == 269)
{
ReadTables ();
continue;
}
if (Number == 256)
{
Length = LastLength;
Distance = LastDist;
LastDist = OldDist[OldDistPtr++ & 3] = Distance;
DestUnpSize -= (LastLength = Length);
while (Length--)
{
UnpBuf[UnpPtr] = UnpBuf[(UnpPtr - Distance) & MAXWINMASK];
UnpPtr = (UnpPtr + 1) & MAXWINMASK;
}
continue;
}
if (Number < 261)
{
Distance = OldDist[(OldDistPtr - (Number - 256)) & 3];
DecodeNumber (RepDecode2Decode (&RD));
Length = LDecode[Number] + 2;
if ((Bits = LBits[Number]) > 0)
{
GetBits ();
Length += BitField >> (16 - Bits);
AddBits (Bits);
}
if (Distance >= 0x40000)
Length++;
if (Distance >= 0x2000)
Length++;
if (Distance >= 0x101)
Length++;
LastDist = OldDist[OldDistPtr++ & 3] = Distance;
DestUnpSize -= (LastLength = Length);
while (Length--)
{
UnpBuf[UnpPtr] = UnpBuf[(UnpPtr - Distance) & MAXWINMASK];
UnpPtr = (UnpPtr + 1) & MAXWINMASK;
}
continue;
}
if (Number < 270)
{
Distance = SDDecode[Number -= 261] + 1;
if ((Bits = SDBits[Number]) > 0)
{
GetBits ();
Distance += BitField >> (16 - Bits);
AddBits (Bits);
}
Length = 2;
LastDist = OldDist[OldDistPtr++ & 3] = Distance;
DestUnpSize -= (LastLength = Length);
while (Length--)
{
UnpBuf[UnpPtr] = UnpBuf[(UnpPtr - Distance) & MAXWINMASK];
UnpPtr = (UnpPtr + 1) & MAXWINMASK;
}
continue;
}
}
ReadLastTables ();
if (FileFound) /* flush buffer */
{
if (UnpPtr < WrPtr)
{
if ((*temp_output_buffer_offset + UnpPtr) > NewLhd.UnpSize)
{
debug_log ("Fatal! Buffer overrun during decompression!");
DestUnpSize = -1;
}
else
{
/* copy extracted data to output buffer */
memcpy (temp_output_buffer + *temp_output_buffer_offset,
&UnpBuf[WrPtr], (0 - WrPtr) & MAXWINMASK);
/* update offset within buffer */
*temp_output_buffer_offset += (0 - WrPtr) & MAXWINMASK;
/* copy extracted data to output buffer */
memcpy (temp_output_buffer + *temp_output_buffer_offset, UnpBuf,
UnpPtr);
/* update offset within buffer */
*temp_output_buffer_offset += UnpPtr;
}
}
else
{
if ((*temp_output_buffer_offset + (UnpPtr - WrPtr)) > NewLhd.UnpSize)
{
debug_log ("Fatal! Buffer overrun during decompression!");
DestUnpSize = -1;
}
else
{
/* copy extracted data to output buffer */
memcpy (temp_output_buffer + *temp_output_buffer_offset,
&UnpBuf[WrPtr], UnpPtr - WrPtr);
/* update offset within buffer */
*temp_output_buffer_offset += UnpPtr - WrPtr;
}
}
}
WrPtr = UnpPtr;
}
unsigned int
UnpRead (unsigned char *Addr, unsigned int Count)
{
int RetCode = 0;
unsigned int I, ReadSize, TotalRead = 0;
unsigned char *ReadAddr = Addr;
if (Count > 0)
{
ReadSize = (unsigned int) ((Count > (unsigned long) UnpPackedSize) ?
(unsigned int) UnpPackedSize : Count);
if (inputfile == NULL)
return 0;
RetCode = fread (ReadAddr, 1, ReadSize, inputfile);
CurUnpRead += RetCode;
ReadAddr += RetCode;
TotalRead += RetCode;
Count -= RetCode;
UnpPackedSize -= RetCode;
}
if (RetCode != -1)
{
RetCode = TotalRead;
if (Encryption)
{
if (Encryption < 20)
{
debug_log ("Old Crypt() not supported!");
}
else
{
for (I = 0; I < (unsigned int) RetCode; I += 16)
DecryptBlock (&Addr[I]);
}
}
}
return RetCode;
}
void
UnpReadBuf (int FirstBuf)
{
int RetCode;
if (FirstBuf)
{
ReadTop = UnpRead (InBuf, sizeof (InBuf));
InAddr = 0;
}
else
{
memcpy (InBuf, &InBuf[sizeof (InBuf) - 32], 32);
InAddr &= 0x1f;
RetCode = UnpRead (&InBuf[32], sizeof (InBuf) - 32);
if (RetCode > 0)
ReadTop = RetCode + 32;
else
ReadTop = InAddr;
}
}
void
ReadTables (void)
{
UBYTE BitLength[BC];
unsigned char Table[MC * 4];
int TableSize, N, I;
if (InAddr > sizeof (InBuf) - 25)
UnpReadBuf (0);
GetBits ();
UnpAudioBlock = (BitField & 0x8000);
if (!(BitField & 0x4000))
memset (UnpOldTable, 0, sizeof (UnpOldTable));
AddBits (2);
if (UnpAudioBlock)
{
UnpChannels = ((BitField >> 12) & 3) + 1;
if (CurChannel >= UnpChannels)
CurChannel = 0;
AddBits (2);
TableSize = MC * UnpChannels;
}
else
TableSize = NC + DC + RC;
for (I = 0; I < BC; I++)
{
GetBits ();
BitLength[I] = (UBYTE) (BitField >> 12);
AddBits (4);
}
MakeDecodeTables (BitLength, BitDecode2Decode (&BD), BC);
Decode2BitDecode (&BD);
I = 0;
while (I < TableSize)
{
if (InAddr > sizeof (InBuf) - 5)
UnpReadBuf (0);
DecodeNumber (BitDecode2Decode (&BD));
if (Number < 16)
{
Table[I] = (Number + UnpOldTable[I]) & 0xf;
I++;
}
else if (Number == 16)
{
GetBits ();
N = (BitField >> 14) + 3;
AddBits (2);
while (N-- > 0 && I < TableSize)
{
Table[I] = Table[I - 1];
I++;
}
}
else
{
if (Number == 17)
{
GetBits ();
N = (BitField >> 13) + 3;
AddBits (3);
}
else
{
GetBits ();
N = (BitField >> 9) + 11;
AddBits (7);
}
while (N-- > 0 && I < TableSize)
Table[I++] = 0;
}
}
if (UnpAudioBlock)
for (I = 0; I < UnpChannels; I++)
{
MakeDecodeTables (&Table[I * MC], MultDecode2Decode (MDPtr[I]), MC);
Decode2MultDecode (MDPtr[I]);
}
else
{
MakeDecodeTables (&Table[0], LitDecode2Decode (&LD), NC);
Decode2LitDecode (&LD);
MakeDecodeTables (&Table[NC], DistDecode2Decode (&DD), DC);
Decode2DistDecode (&DD);
MakeDecodeTables (&Table[NC + DC], RepDecode2Decode (&RD), RC);
Decode2RepDecode (&RD);
}
memcpy (UnpOldTable, Table, sizeof (UnpOldTable));
}
static void
ReadLastTables (void)
{
if (ReadTop >= InAddr + 5)
{
if (UnpAudioBlock)
{
DecodeNumber (MultDecode2Decode (MDPtr[CurChannel]));
if (Number == 256)
ReadTables ();
}
else
{
DecodeNumber (LitDecode2Decode (&LD));
if (Number == 269)
ReadTables ();
}
}
}
static void
MakeDecodeTables (unsigned char *LenTab, struct Decode *Dec, int Size)
{
int LenCount[16], TmpPos[16], I;
long M, N;
memset (LenCount, 0, sizeof (LenCount));
for (I = 0; I < Size; I++)
LenCount[LenTab[I] & 0xF]++;
LenCount[0] = 0;
for (TmpPos[0] = Dec->DecodePos[0] = Dec->DecodeLen[0] = 0, N = 0, I = 1;
I < 16; I++)
{
N = 2 * (N + LenCount[I]);
M = N << (15 - I);
if (M > 0xFFFF)
M = 0xFFFF;
Dec->DecodeLen[I] = (unsigned int) M;
TmpPos[I] = Dec->DecodePos[I] = Dec->DecodePos[I - 1] + LenCount[I - 1];
}
for (I = 0; I < Size; I++)
if (LenTab[I] != 0)
Dec->DecodeNum[TmpPos[LenTab[I] & 0xF]++] = I;
Dec->MaxNum = Size;
}
static void
DecodeNumber (struct Decode *Deco)
/* *** 52.6% of all CPU time is spent within this function!!! */
{
unsigned int I;
register unsigned int N;
GetBits ();
#ifdef _USE_ASM
__asm__ __volatile__ ("andl $0xFFFFFFFE, %%eax\n"
" movl %%eax, %1\n"
" cmpl 8*4(%%edx), %%eax /* 5379 */\n"
" jae else_G\n"
"\n"
" cmpl 4*4(%%edx), %%eax\n"
" jae else_F\n"
"\n"
" cmpl 2*4(%%edx), %%eax\n"
" jae else_C\n"
"\n"
" cmpl 1*4(%%edx), %%eax\n"
"\n"
" jae else_1\n"
" movl $1, %0\n"
" jmp next_1\n"
" else_1: \n"
" movl $2, %0\n"
" next_1:\n"
" \n"
" jmp next_C\n"
" else_C: \n"
"\n"
" cmpl 3*4(%%edx), %%eax \n"
" jae else_2\n"
" movl $3, %0\n"
" jmp next_2\n"
" else_2: \n"
" movl $4, %0\n"
" next_2:\n"
"\n"
" next_C: \n"
"\n"
" jmp next_F\n"
" else_F:\n"
"\n"
" cmpl 6*4(%%edx), %%eax\n"
" jae else_E\n"
"\n"
" cmpl 5*4(%%edx), %%eax\n"
" jae else_3\n"
" movl $5, %0 \n"
" jmp next_3\n"
" else_3: \n"
" movl $6, %0 \n"
" next_3:\n"
"\n"
" jmp next_E\n"
" else_E: \n"
"\n"
" cmpl 7*4(%%edx), %%eax\n"
" jae else_4\n"
" movl $7, %0 \n"
" jmp next_4\n"
" else_4: \n"
" movl $8, %0 \n"
" next_4:\n"
"\n"
" next_E:\n"
"\n"
" next_F:\n"
"\n"
" jmp next_G\n"
" else_G:\n"
"\n"
" cmpl 12*4(%%edx), %%eax\n"
" jae else_D\n"
"\n"
" cmpl 10*4(%%edx), %%eax\n"
" jae else_B\n"
"\n"
" cmpl 9*4(%%edx), %%eax\n"
" jae else_5\n"
" movl $9, %0 \n"
" jmp next_5\n"
" else_5: \n"
" movl $10, %0 \n"
" next_5:\n"
"\n"
" jmp next_B\n"
" else_B: \n"
"\n"
" cmpl 11*4(%%edx), %%eax\n"
" \n"
" jae else_6\n"
" movl $11, %0 \n"
" jmp next_6\n"
" else_6: \n"
" movl $12, %0 \n"
" next_6:\n"
"\n"
" next_B:\n"
" \n"
" \n"
" jmp next_D\n"
" else_D: \n"
"\n"
" cmpl 14*4(%%edx), %%eax\n"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -