#include <windows.h>
#include "..\\dtr.hpp"
BYTE *hr_d_output;
BYTE *hr_d_input;
BYTE hr_d_tagbyte;/*буфер для битов.*/
BYTE __index = 7;
BYTE hr_d_getbit(void)
{
BYTE bit[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
__index = (__index + 1) % 8;
if(__index == 0) hr_d_tagbyte = *hr_d_input++;
return (hr_d_tagbyte & bit[__index]) == 0 ? 0 : 1;
}
WORD hr_d_getlen(void)
{
WORD tmp, result = 1;
do
{
tmp = (hr_d_getbit() << 1) + hr_d_getbit();
result += tmp;
} while(tmp == 0x03 && result != 0x10);
return(result);
}
WORD hr_d_getdist(void)
{
WORD result;volatile WORD tmp;
if(hr_d_getbit())
{
result = 0xff00 + *hr_d_input++;
}
else
{
result = 0xffff;
tmp = (hr_d_getbit() << 1) + hr_d_getbit() + 0xffff-3;
for(; tmp; tmp++) result = (result << 1) + hr_d_getbit() - 1;
if(result == 0xffff - 30) result = *hr_d_input++;
result = (result << 8) + *hr_d_input++;
}
return (result);
}
void dehrust(BYTE* source, BYTE* destination)
{
__index = 7;
WORD len;
short offs;
hr_d_input = source + 6;
hr_d_output = destination;
*hr_d_output++ = *hr_d_input++;
while(true)
{
if(!hr_d_getbit())
{
len = hr_d_getlen();
offs = 0xffff;
if(len == 4)
{
if(hr_d_getbit())
{
len = *hr_d_input++;
if(len == 0)
break;
else
if(len < 16) len = (len << 8) + *hr_d_input++;
offs = hr_d_getdist();
for(; len; len--) *hr_d_output = *(hr_d_output++ + offs);
}
else
{
len = 0;
for(int i = 4; i; i--) len = (len << 1) + hr_d_getbit();
len += 6;
len <<= 1;
for(; len; len--) *hr_d_output++ = *hr_d_input++;
}
}
else
{
if(len > 4) len--;
if(len == 1)
{
for(int i = 3; i; i--) offs = (offs << 1) + hr_d_getbit();
}
else
{
if(len == 2)
offs = 0xff00 + *hr_d_input++;
else
offs = hr_d_getdist();
}
for(; len; len--) *hr_d_output = *(hr_d_output++ + offs);
}
}
else
{
*hr_d_output++ = *hr_d_input++;
}
}
for(int i = 0; i < 6; i++) *hr_d_output++ = source[i];
}
bool WINAPI extract(HoHdr *hdr, const BYTE *source, DWORD sourceSize, BYTE *unpackBuffer, DWORD *noUnpackedBytes, DWORD)
{
*noUnpackedBytes = *(WORD*)(source + 4);
if(source[3] & 0x80)
CopyMemory(unpackBuffer, source + 8, *noUnpackedBytes);
else
{
dehrust((BYTE*)source + 8, unpackBuffer);
#define ACE_notSUPPORT
#ifdef ACE_SUPPORT
// ACE detector
int i;
WORD len = hdr->length;
bool ace = true;
DWORD extraLen = sourceSize - len;
if(extraLen >= 14) extraLen = 14;
for(i = 0; i < extraLen; ++i)
if(source[i] != source[len+i])
{
ace = false;
break;
}
WORD maxLen = 128;
WORD lineLen = 0;
for(i = 0; i < *noUnpackedBytes && ace ; ++i)
{
if(unpackBuffer[i] == 0)
{
// sprites?
if((*noUnpackedBytes-i-1)%9*32 != 0)
{
ace = false;
break;
}
*noUnpackedBytes = i; // let's crop sprites
break;
}
else
{
if(lineLen > maxLen)
{
ace = false;
break;
}
++lineLen;
if(unpackBuffer[i] == 0x0d) lineLen = 0;
}
}
if(ace)
{
for(i = 0; i < *noUnpackedBytes; ++i)
if((unpackBuffer[i] > 0 && unpackBuffer[i] < 9) || (unpackBuffer[i] > 13 && unpackBuffer[i] < 21)) unpackBuffer[i] = ' ';
}
// END of ACE detector
#endif
}
return true;
}
bool WINAPI detect(DetectorResult &result, const char*, const HoHdr*, const BYTE *data, int file_size)
{
if(data[0] != 'h' || data[1] != 'r' || data[2] != '2') return false;
WORD size = *(WORD*)(data + 4);
WORD packed_size = *(WORD*)(data + 6);
if(packed_size > size || packed_size > file_size) return false;
result.action = do_extract;
lstrcpy(result.title, "[hrust 2.1]");
return true;
}
[свернуть]