Removed RAR support due to licensing conflicts with the GNU GPL.

This commit is contained in:
mudlord 2007-11-13 08:58:13 +00:00
parent bdbda96961
commit 46bbb9be39
28 changed files with 4 additions and 5837 deletions

View File

@ -201,14 +201,6 @@
RelativePath=".\fex\Gzip_Reader.h"
>
</File>
<File
RelativePath=".\fex\Rar_Extractor.cpp"
>
</File>
<File
RelativePath=".\fex\Rar_Extractor.h"
>
</File>
<File
RelativePath=".\fex\Single_File_Extractor.cpp"
>
@ -217,14 +209,6 @@
RelativePath=".\fex\Single_File_Extractor.h"
>
</File>
<File
RelativePath=".\fex\unrarlib.cpp"
>
</File>
<File
RelativePath=".\fex\unrarlib.h"
>
</File>
<File
RelativePath=".\fex\unzip.cpp"
>
@ -301,46 +285,6 @@
>
</File>
</Filter>
<Filter
Name="rar"
>
<File
RelativePath=".\unrar\archive.cpp"
>
</File>
<File
RelativePath=".\unrar\model.cpp"
>
</File>
<File
RelativePath=".\unrar\Rar_Extractor_Impl.cpp"
>
</File>
<File
RelativePath=".\unrar\rarmisc.cpp"
>
</File>
<File
RelativePath=".\unrar\rarvm.cpp"
>
</File>
<File
RelativePath=".\unrar\suballoc.cpp"
>
</File>
<File
RelativePath=".\unrar\unpack.cpp"
>
</File>
<File
RelativePath=".\unrar\unpack15.cpp"
>
</File>
<File
RelativePath=".\unrar\unpack20.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"

View File

@ -1,191 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#include "blargg_common.h"
#if FEX_ENABLE_RAR
#include "Rar_Extractor.h"
#include "unrar/rar.hpp"
#include "blargg_source.h"
const char end_of_rar [] = "Unexpected end of RAR archive";
Rar_Extractor::Rar_Extractor() : File_Extractor( fex_rar_type )
{
impl = 0;
}
static File_Extractor* new_rar() { return BLARGG_NEW Rar_Extractor; }
fex_type_t_ const fex_rar_type [1] = {{ "RAR", &new_rar }};
void Rar_Extractor::close_()
{
delete impl;
impl = 0;
}
Rar_Extractor::~Rar_Extractor() { close(); }
blargg_err_t Rar_Extractor::open_()
{
RETURN_ERR( file().seek( 0 ) );
CHECK_ALLOC( impl = BLARGG_NEW Rar_Extractor_Impl( &file() ) );
CHECK_ALLOC( !setjmp( impl->jmp_env ) );
impl->Unp.Init( 0 );
if ( !impl->arc.IsArchive() )
return fex_wrong_file_type;
RETURN_ERR( impl->arc.IsArchive2() );
index = -1;
can_extract = true;
return next_item();
}
blargg_err_t Rar_Extractor::rewind_()
{
assert( impl );
close_();
return open_();
}
blargg_err_t Rar_Extractor::next_item()
{
CHECK_ALLOC( !setjmp( impl->jmp_env ) );
index++;
for ( ;; impl->arc.SeekToNext() )
{
blargg_err_t err = impl->arc.ReadHeader();
if ( err == end_of_rar )
{
set_done();
break;
}
if ( err )
return err;
HEADER_TYPE type = (HEADER_TYPE) impl->arc.GetHeaderType();
if ( type == ENDARC_HEAD )
{
// no files beyond this point
set_done();
break;
}
// skip non-files
if ( type != FILE_HEAD )
{
if ( type != NEWSUB_HEAD && type != PROTECT_HEAD )
dprintf( "Skipping unknown RAR block type: %X\n", (int) type );
continue;
}
// skip label
if ( impl->arc.NewLhd.HostOS <= HOST_WIN32 && (impl->arc.NewLhd.FileAttr & 8) )
continue;
// skip links
if ( (impl->arc.NewLhd.FileAttr & 0xF000) == 0xA000 )
continue;
// skip directories
if ( (impl->arc.NewLhd.Flags & LHD_WINDOWMASK) == LHD_DIRECTORY )
continue;
set_info( impl->arc.NewLhd.UnpSize, impl->arc.NewLhd.FileName );
break;
}
extracted = false;
return 0;
}
blargg_err_t Rar_Extractor::next_()
{
CHECK_ALLOC( !setjmp( impl->jmp_env ) );
if ( !extracted && impl->arc.Solid )
{
if ( is_scan_only() )
{
can_extract = false;
}
else
{
// must extract every file in a solid archive
Null_Writer out;
RETURN_ERR( impl->extract( out, false ) );
}
}
impl->arc.SeekToNext();
return next_item();
}
blargg_err_t Rar_Extractor::extract( Data_Writer& out )
{
if ( !impl || extracted )
return Data_Reader::eof_error;
CHECK_ALLOC( !setjmp( impl->jmp_env ) );
if ( !can_extract )
{
int saved_index = index;
RETURN_ERR( rewind_() );
scan_only( false );
while ( index < saved_index )
{
if ( done() )
return "Corrupt RAR archive";
RETURN_ERR( next_() );
}
assert( can_extract );
}
extracted = true;
impl->write_error = 0;
RETURN_ERR( impl->extract( out ) );
return impl->write_error;
}
// Rar_Extractor_Impl
void Rar_Extractor_Impl::Seek( long n )
{
if ( reader->seek( n ) )
check( false );
}
long Rar_Extractor_Impl::Tell() { return reader->tell(); }
long Rar_Extractor_Impl::Read( void* p, long n ) { return reader->read_avail( p, n ); }
long Rar_Extractor_Impl::Size() { return reader->size(); }
void Rar_Extractor_Impl::UnpWrite( byte const* out, uint count )
{
if ( !write_error )
write_error = writer->write( out, count );
if ( MaintainCRC )
{
if ( arc.OldFormat )
UnpFileCRC = OldCRC( (ushort) UnpFileCRC, out, count );
else
UnpFileCRC = CRC( UnpFileCRC, out, count );
}
}
#endif

View File

@ -1,27 +0,0 @@
// RAR archive extractor
// File_Extractor 0.4.2
#ifndef RAR_EXTRACTOR_H
#define RAR_EXTRACTOR_H
#include "File_Extractor.h"
class Rar_Extractor : public File_Extractor {
public:
Rar_Extractor();
~Rar_Extractor();
blargg_err_t extract( Data_Writer& );
protected:
blargg_err_t open_();
blargg_err_t next_();
blargg_err_t rewind_();
void close_();
private:
class Rar_Extractor_Impl* impl;
int index;
bool can_extract;
bool extracted;
blargg_err_t next_item();
};
#endif

View File

@ -1,127 +0,0 @@
// File_Extractor 0.4.2. http://www.slack.net/~ant/
#include "unrarlib.h"
#include "File_Extractor.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* Copyright (C) 2005-2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
// log error message to stderr when debugging
inline const char* log_error( const char* str )
{
#ifndef NDEBUG
if ( str )
fprintf( stderr, "unrarlib Error: %s\n", str );
#endif
return str;
}
int urarlib_list( const char* path, ArchiveList_struct** list )
{
ArchiveList_struct** tail = list;
int count = 0;
*list = 0;
File_Extractor* fex = 0;
if ( log_error( fex_open( path, &fex ) ) )
goto error;
fex->scan_only(); // significantly faster for solid archives
while ( !fex->done() )
{
ArchiveList_struct* item = (ArchiveList_struct*) calloc( sizeof *item, 1 );
if ( !item )
goto error;
// insert at end
*tail = item;
item->next = 0;
tail = &item->next;
count++;
item->item.NameSize = strlen( fex->name() );
item->item.Name = (char*) malloc( item->item.NameSize + 1 );
if ( !item->item.Name )
goto error;
strcpy( item->item.Name, fex->name() );
item->item.UnpSize = fex->size();
if ( log_error( fex->next() ) )
goto error;
}
if ( 0 )
{
error:
urarlib_freelist( *list );
*list = 0;
count = 0;
}
delete fex;
return count;
}
void urarlib_freelist( ArchiveList_struct* node )
{
while ( node )
{
ArchiveList_struct* next = node->next;
free( node->item.Name );
free( node );
node = next;
}
}
int urarlib_get( void* output, unsigned long* size, const char* filename,
const char* path, const char* password )
{
assert( !password ); // password not supported
*(void**) output = 0;
*size = 0;
void* buf = 0;
File_Extractor* fex = 0;
if ( log_error( fex_open( path, &fex ) ) )
goto error;
while ( !fex->done() )
{
if ( !strcmp( fex->name(), filename ) )
{
buf = malloc( fex->size() );
if ( !buf || log_error( fex->read( buf, fex->size() ) ) )
goto error;
*(void**) output = buf;
*size = fex->size();
delete fex;
return true;
}
if ( log_error( fex->next() ) )
goto error;
}
// not found
error:
free( buf );
delete fex;
return false;
}

View File

@ -1,56 +0,0 @@
/* Accesses file archives using unrarlib 0.4.0 (UniquE RAR File Library) interface.
With this you can use File_Extractor in place of unrarlib with minimal
changes to your code. If you're writing new code, use the fex.h interface. */
/* File_Extractor 0.4.2 */
#ifndef URARLIB_H
#define URARLIB_H
#ifdef __cplusplus
extern "C" {
#endif
struct RAR20_archive_entry
{
/* Only Name, NameSize, and UnpSize are valid; all other fields are set to zero */
char* Name;
unsigned short NameSize;
unsigned long PackSize;
unsigned long UnpSize;
unsigned char HostOS;
unsigned long FileCRC;
unsigned long FileTime;
unsigned char UnpVer;
unsigned char Method;
unsigned long FileAttr;
};
typedef struct ArchiveList_struct
{
struct RAR20_archive_entry item;
struct ArchiveList_struct* next; /* next entry in list, or NULL if end of list */
} ArchiveList_struct;
/* Allocate and set *list_out to first node of linked list of files from file archive at
'archive_path' and return number of items in list. Use urarlib_freelist() to free memory
used by the list. */
int urarlib_list( const char* archive_path, ArchiveList_struct** list_out );
/* Extract 'filename' from a file archive at 'archive_path' into internal buffer.
Sets *buffer_out to beginning of data and *size_out to number of bytes extracted.
Returns true if successful otherwise false. Password is not supported (must be NULL).
Caller must free() returned buffer when done with it.
Note: buffer_out is treated as void**, but declared as void* to match original urarlib.h. */
int urarlib_get( void* buffer_out, unsigned long* size_out, const char* filename,
const char* archive_path, const char* password );
/* Free memory used by list of nodes returned by urarlib_list(). Pointer must be that
returned by urarlib_list() (that is, the first node in the list). */
void urarlib_freelist( ArchiveList_struct* list );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,105 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#include "rar.hpp"
#include <assert.h>
Rar_Extractor_Impl::Rar_Extractor_Impl( File_Reader* in ) :
reader( in ),
arc( this ),
Unp( this, this ),
Buffer( this )
{
first_file = true;
InitCRC();
}
void rar_out_of_memory( Rar_Error_Handler* eh )
{
longjmp( eh->jmp_env, 1 );
}
int Rar_Extractor_Impl::UnpRead( byte* out, uint count )
{
if ( count <= 0 )
return 0;
if ( count > (uint) UnpPackedSize )
count = UnpPackedSize;
long result = Read( out, count );
if ( result >= 0 )
UnpPackedSize -= result;
return result;
}
void Rar_Extractor_Impl::UnstoreFile( Int64 DestUnpSize )
{
Buffer.Alloc( 0x10000 );
while ( true )
{
unsigned int result = UnpRead( &Buffer[0], Buffer.Size() );
if ( result == 0 || (int) result == -1 )
break;
result = ((Int64) result < DestUnpSize ? result : int64to32( DestUnpSize ));
UnpWrite( &Buffer[0], result );
if ( DestUnpSize >= 0 )
DestUnpSize -= result;
}
Buffer.Reset();
}
const char* Rar_Extractor_Impl::extract( Data_Writer& rar_writer, bool check_crc )
{
assert( arc.GetHeaderType() == FILE_HEAD );
if ( arc.NewLhd.Flags & (LHD_SPLIT_AFTER | LHD_SPLIT_BEFORE) )
return "Segmented RAR not supported";
if ( arc.NewLhd.Flags & LHD_PASSWORD )
return "Encrypted RAR archive not supported";
if ( arc.NewLhd.UnpVer < 13 || arc.NewLhd.UnpVer > UNP_VER )
return "RAR file uses an unsupported format (too old or too recent)";
Seek( arc.NextBlockPos - arc.NewLhd.FullPackSize );
UnpFileCRC = arc.OldFormat ? 0 : 0xFFFFFFFF;
PackedCRC = 0xFFFFFFFF;
UnpPackedSize = arc.NewLhd.FullPackSize;
MaintainCRC = check_crc;
this->writer = &rar_writer;
if ( arc.NewLhd.Method == 0x30 )
{
UnstoreFile( arc.NewLhd.FullUnpSize );
}
else
{
Unp.SetDestSize( arc.NewLhd.FullUnpSize );
if ( arc.NewLhd.UnpVer <= 15 )
Unp.DoUnpack( 15, arc.Solid && !first_file );
else
Unp.DoUnpack( arc.NewLhd.UnpVer, arc.NewLhd.Flags & LHD_SOLID);
}
first_file = false;
arc.SeekToNext();
if ( check_crc )
{
unsigned long correct = arc.NewLhd.FileCRC;
if ( !arc.OldFormat )
correct = ~correct;
if ( (UnpFileCRC ^ correct) & 0xFFFFFFFF )
return "CRC error";
}
return 0;
}

View File

@ -1,47 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#ifndef RAR_EXTRACTOR_IMPL_H
#define RAR_EXTRACTOR_IMPL_H
#include "rar.hpp"
extern const char end_of_rar [];
class Data_Writer;
class File_Reader;
class Rar_Extractor_Impl : public Rar_Allocator {
public:
void Seek( long );
long Tell();
long Read( void*, long );
long Size();
int UnpRead( byte*, uint );
void UnpWrite( byte const*, uint );
jmp_buf jmp_env;
private:
File_Reader* reader;
Archive arc;
bool first_file;
Unpack Unp;
Rar_Array<byte> Buffer;
const char* write_error; // once write error occurs, no more writes are made
Data_Writer* writer;
Int64 UnpPackedSize;
uint UnpFileCRC,PackedCRC;
bool MaintainCRC;
const char* extract( Data_Writer&, bool check_crc = 1 );
Rar_Extractor_Impl( File_Reader* in );
void UnstoreFile( Int64 );
friend class Rar_Extractor;
};
#endif

View File

@ -1,371 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#include "rar.hpp"
#include <assert.h>
#ifndef check
#define check( expr ) ((void) 0)
#endif
Archive::Archive( Rar_Extractor_Impl* impl_ ) : NewLhd( impl_ ), SubHead( impl_ ), Raw( impl_ )
{
impl = impl_;
OldFormat=false;
Solid=false;
LastReadBlock=0;
CurBlockPos=0;
NextBlockPos=0;
memset(&NewMhd,0,sizeof(NewMhd));
NewMhd.HeadType=MAIN_HEAD;
NewMhd.HeadSize=SIZEOF_NEWMHD;
HeaderCRC=0;
}
bool Archive::IsSignature(byte *D)
{
OldFormat = false;
if ( D [0] != 0x52 )
return false;
if ( D [1] == 0x45 && D [2] == 0x7E && D [3] == 0x5E )
{
OldFormat = true;
return true;
}
if ( D [1] == 0x61 && D [2] == 0x72 && D [3] == 0x21 &&
D [4] == 0x1A && D [5] == 0x07 && D [6] == 0x00)
return true;
return false;
}
int Archive::IsArchive()
{
if ( impl->Read( MarkHead.Mark,SIZEOF_MARKHEAD ) != SIZEOF_MARKHEAD )
return 0;
if ( !IsSignature( MarkHead.Mark ) )
return 0;
return 1;
}
const char* Archive::IsArchive2()
{
if (OldFormat)
impl->Seek(0);
const char* error = ReadHeader();
if ( error )
return error;
SeekToNext();
if ( OldFormat )
{
NewMhd.Flags = OldMhd.Flags & 0x3f;
NewMhd.HeadSize = OldMhd.HeadSize;
}
else if ( HeaderCRC != NewMhd.HeadCRC )
{
return "RAR header CRC is wrong";
}
if ( NewMhd.Flags & MHD_VOLUME )
return "Split RAR files are not supported";
if ( NewMhd.Flags & MHD_PASSWORD )
return "Encrypted RAR files are not supported";
Solid = (NewMhd.Flags & MHD_SOLID) != 0;
return NULL;
}
void Archive::SeekToNext()
{
impl->Seek( NextBlockPos );
}
// RawRead
RawRead::RawRead( Rar_Extractor_Impl* impl_ ) : Data( impl_ )
{
impl = impl_;
ReadPos = 0;
DataSize = 0;
}
void RawRead::Reset()
{
check( ReadPos == DataSize );
ReadPos = 0;
DataSize = 0;
Data.Reset();
}
void RawRead::Read( int count )
{
if ( count )
{
Data.Alloc( DataSize + count );
DataSize += impl->Read( &Data [DataSize], count );
}
}
void RawRead::get8( byte& out )
{
out = Data [ReadPos];
ReadPos++;
}
void RawRead::get16( ushort& out )
{
out = Data [ReadPos] + (Data [ReadPos + 1] << 8);
ReadPos += 2;
}
void RawRead::get32( uint& out )
{
out=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+
(Data[ReadPos+3]<<24);
ReadPos+=4;
}
void RawRead::Get( byte* out, int count )
{
memcpy( out, &Data [ReadPos], count );
ReadPos += count;
}
uint RawRead::GetCRC( bool partial )
{
uint crc = 0xFFFFFFFF;
if ( DataSize > 2 )
crc = CRC( crc, &Data[2], (partial ? ReadPos : DataSize) - 2 );
return ~crc & 0xFFFF;
}
// Archive::ReadHeader()
const char* Archive::ReadHeader()
{
CurBlockPos = impl->Tell();
if ( OldFormat )
return ReadOldHeader();
Raw.Reset();
Raw.Read( SIZEOF_SHORTBLOCKHEAD );
if ( Raw.Size() == 0 )
{
Int64 ArcSize = impl->Size();
if ( CurBlockPos > ArcSize || NextBlockPos > ArcSize )
return "RAR file is missing data at the end";
return end_of_rar;
}
check( Raw.Size() == SIZEOF_SHORTBLOCKHEAD );
Raw.get16( ShortBlock.HeadCRC );
byte HeadType;
Raw.get8( HeadType );
ShortBlock.HeadType=(HEADER_TYPE)HeadType;
Raw.get16( ShortBlock.Flags );
Raw.get16( ShortBlock.HeadSize );
if ( ShortBlock.HeadSize<SIZEOF_SHORTBLOCKHEAD)
return "CRC error in RAR file";
if ( ShortBlock.HeadType==COMM_HEAD)
Raw.Read( SIZEOF_COMMHEAD-SIZEOF_SHORTBLOCKHEAD );
else
if ( ShortBlock.HeadType==MAIN_HEAD && (ShortBlock.Flags & MHD_COMMENT)!=0)
Raw.Read( SIZEOF_NEWMHD-SIZEOF_SHORTBLOCKHEAD );
else
Raw.Read( ShortBlock.HeadSize-SIZEOF_SHORTBLOCKHEAD );
NextBlockPos = CurBlockPos + ShortBlock.HeadSize;
switch ( ShortBlock.HeadType )
{
case MAIN_HEAD:
*(BaseBlock*)&NewMhd=ShortBlock;
Raw.get16( NewMhd.HighPosAV );
Raw.get32( NewMhd.PosAV );
break;
case ENDARC_HEAD:
// ignore
break;
case FILE_HEAD:
case NEWSUB_HEAD:
{
FileHeader *hd=ShortBlock.HeadType==FILE_HEAD ? &NewLhd:&SubHead;
*(BaseBlock*)hd=ShortBlock;
Raw.get32( hd->PackSize );
Raw.get32( hd->UnpSize );
Raw.get8( hd->HostOS );
Raw.get32( hd->FileCRC );
Raw.get32( hd->FileTime );
Raw.get8( hd->UnpVer );
Raw.get8( hd->Method );
Raw.get16( hd->NameSize );
Raw.get32( hd->FileAttr );
hd->HighPackSize=hd->HighUnpSize=0;
if (hd->Flags & LHD_LARGE)
{
Raw.get32( hd->HighPackSize );
Raw.get32( hd->HighUnpSize );
}
assert( hd->UnpSize != 0xFFFFFFFF );
if ( hd->HighPackSize || hd->HighUnpSize )
return "Huge RAR archives not supported";
hd->FullPackSize = hd->PackSize;
hd->FullUnpSize = hd->UnpSize;
char FileName[NM*4];
int NameSize=Min(hd->NameSize,sizeof(FileName)-1 );
Raw.Get((byte*)FileName,NameSize );
FileName[NameSize]=0;
strncpy(hd->FileName,FileName,sizeof(hd->FileName) );
hd->FileName[sizeof(hd->FileName)-1]=0;
if (hd->HeadType==NEWSUB_HEAD)
{
int DataSize=hd->HeadSize-hd->NameSize-SIZEOF_NEWLHD;
if (hd->Flags & LHD_SALT)
DataSize-=SALT_SIZE;
if (DataSize>0)
{
hd->SubData.Alloc(DataSize );
Raw.Get(&hd->SubData[0],DataSize );
//if ( !strcmp( hd->FileName, SUBHEAD_TYPE_RR ) )
//byte *D=&hd->SubData[8];
}
}
else if (hd->HeadType==FILE_HEAD)
{
hd->Flags &= ~LHD_UNICODE;
if (NewLhd.UnpVer<20 && (NewLhd.FileAttr & 0x10))
NewLhd.Flags|=LHD_DIRECTORY;
if (NewLhd.HostOS>=HOST_MAX)
{
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
NewLhd.FileAttr=0x10;
else
NewLhd.FileAttr=0x20;
}
}
if (hd->Flags & LHD_SALT)
Raw.Get(hd->Salt,SALT_SIZE );
if (hd->Flags & LHD_EXTTIME)
{
ushort Flags;
Raw.get16( Flags );
for (int I=0;I<4;I++)
{
uint rmode=Flags>>(3-I)*4;
if ((rmode & 8)==0)
continue;
if (I!=0)
{
uint DosTime;
Raw.get32( DosTime );
}
// skip time info
for ( int n = rmode & 3; n--; )
{
byte CurByte;
Raw.get8( CurByte );
}
}
}
NextBlockPos += hd->FullPackSize;
HeaderCRC = Raw.GetCRC( hd->Flags & LHD_COMMENT );
if ( hd->HeadCRC != HeaderCRC )
return "RAR file header CRC is incorrect";
}
break;
default:
if (ShortBlock.Flags & LONG_BLOCK)
{
uint DataSize;
Raw.get32( DataSize );
NextBlockPos += DataSize;
}
break;
}
HeaderCRC = Raw.GetCRC( false );
CurHeaderType = ShortBlock.HeadType;
if ( NextBlockPos <= CurBlockPos )
return "CRC error in RAR block header";
return Raw.Size() ? NULL : end_of_rar;
}
const char* Archive::ReadOldHeader()
{
Raw.Reset();
if (CurBlockPos<=SFXSize)
{
Raw.Read(SIZEOF_OLDMHD );
Raw.Get(OldMhd.Mark,4 );
Raw.get16( OldMhd.HeadSize );
Raw.get8( OldMhd.Flags );
NextBlockPos=CurBlockPos+OldMhd.HeadSize;
CurHeaderType=MAIN_HEAD;
}
else
{
OldFileHeader OldLhd;
Raw.Read(SIZEOF_OLDLHD );
NewLhd.HeadType=FILE_HEAD;
Raw.get32( NewLhd.PackSize );
Raw.get32( NewLhd.UnpSize );
Raw.get16( OldLhd.FileCRC );
Raw.get16( NewLhd.HeadSize );
Raw.get32( NewLhd.FileTime );
Raw.get8( OldLhd.FileAttr );
Raw.get8( OldLhd.Flags );
Raw.get8( OldLhd.UnpVer );
Raw.get8( OldLhd.NameSize );
Raw.get8( OldLhd.Method );
NewLhd.Flags=OldLhd.Flags|LONG_BLOCK;
NewLhd.UnpVer=(OldLhd.UnpVer==2) ? 13 : 10;
NewLhd.Method=OldLhd.Method+0x30;
NewLhd.NameSize=OldLhd.NameSize;
NewLhd.FileAttr=OldLhd.FileAttr;
NewLhd.FileCRC=OldLhd.FileCRC;
NewLhd.FullPackSize=NewLhd.PackSize;
NewLhd.FullUnpSize=NewLhd.UnpSize;
Raw.Read(OldLhd.NameSize );
Raw.Get((byte*)NewLhd.FileName,OldLhd.NameSize );
NewLhd.FileName[OldLhd.NameSize]=0;
if (Raw.Size()!=0)
NextBlockPos=CurBlockPos+NewLhd.HeadSize+NewLhd.PackSize;
CurHeaderType=FILE_HEAD;
}
return (NextBlockPos > CurBlockPos && Raw.Size()) ? NULL : end_of_rar;
}

View File

@ -1,65 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#ifndef _RAR_ARCHIVE_
#define _RAR_ARCHIVE_
class RawRead {
private:
Rar_Array<byte> Data;
Rar_Extractor_Impl* impl;
int DataSize;
int ReadPos;
public:
RawRead( Rar_Extractor_Impl* );
~RawRead() { Reset(); }
void Reset();
void Read(int Size);
void get8( byte& out );
void get16( ushort& out );
void get32( uint& out );
void Get(byte *Field,int Size);
uint GetCRC( bool partial );
int Size() {return DataSize;}
};
class Archive {
public:
Archive( Rar_Extractor_Impl* );
int IsArchive();
const char* IsArchive2();
const char* ReadHeader();
void SeekToNext();
int GetHeaderType() {return(CurHeaderType);};
BaseBlock ShortBlock;
MainHeader NewMhd;
FileHeader NewLhd;
FileHeader SubHead;
Int64 CurBlockPos;
Int64 NextBlockPos;
bool OldFormat;
bool Solid;
enum { SFXSize = 0 }; // we don't support self-extracting archive data at the beginning
ushort HeaderCRC;
private:
RawRead Raw;
Rar_Error_Handler* impl;
MarkHeader MarkHead;
OldMainHeader OldMhd;
int LastReadBlock;
int CurHeaderType;
bool IsSignature(byte *D);
const char* ReadOldHeader();
};
#endif

View File

@ -1,94 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#ifndef _RAR_ARRAY_
#define _RAR_ARRAY_
template <class T>
class Rar_Array {
public:
Rar_Array( Rar_Error_Handler* eh )
{
error_handler = eh;
CleanData();
}
Rar_Array( int Size, Rar_Error_Handler* );
~Rar_Array() { free( Buffer ); }
T& operator [] ( int Item ) { return Buffer [Item]; }
int Size() { return BufSize; }
void Add(int Items);
void Alloc(int Items);
void Reset();
void Push(T Item);
private:
T *Buffer;
int BufSize;
int AllocSize;
Rar_Error_Handler* error_handler;
void CleanData()
{
Buffer = NULL;
BufSize = 0;
AllocSize = 0;
}
};
template <class T>
Rar_Array<T>::Rar_Array( int Size, Rar_Error_Handler* eh )
{
error_handler = eh;
AllocSize=BufSize=Size;
Buffer=(T *)malloc(sizeof(T)*Size);
if (Buffer==NULL && BufSize!=0)
rar_out_of_memory( error_handler );
}
template <class T>
void Rar_Array<T>::Add(int Items)
{
BufSize+=Items;
if (BufSize>AllocSize)
{
int Suggested=AllocSize+AllocSize/4+32;
int NewSize = BufSize;
if ( NewSize < Suggested )
NewSize = Suggested;
Buffer=(T *)realloc(Buffer,NewSize*sizeof(T));
if (Buffer==NULL)
rar_out_of_memory( error_handler );
AllocSize=NewSize;
}
}
template <class T>
void Rar_Array<T>::Alloc(int Items)
{
if ( Items > AllocSize )
Add( Items - BufSize );
else
BufSize = Items;
}
template <class T>
void Rar_Array<T>::Reset()
{
free( Buffer );
CleanData();
}
template <class T>
void Rar_Array<T>::Push(T Item)
{
Add( 1 );
(*this) [Size() - 1] = Item;
}
#endif

View File

@ -1,127 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#ifndef _RAR_HEADERS_
#define _RAR_HEADERS_
#define SIZEOF_MARKHEAD 7
#define SIZEOF_OLDMHD 7
#define SIZEOF_NEWMHD 13
#define SIZEOF_OLDLHD 21
#define SIZEOF_NEWLHD 32
#define SIZEOF_SHORTBLOCKHEAD 7
#define SIZEOF_SUBBLOCKHEAD 14
#define SIZEOF_COMMHEAD 13
#define UNP_VER 29
#define MHD_VOLUME 0x0001
#define MHD_COMMENT 0x0002
#define MHD_SOLID 0x0008
#define MHD_PASSWORD 0x0080
#define LHD_SPLIT_BEFORE 0x0001
#define LHD_SPLIT_AFTER 0x0002
#define LHD_PASSWORD 0x0004
#define LHD_COMMENT 0x0008
#define LHD_SOLID 0x0010
#define LHD_WINDOWMASK 0x00e0
#define LHD_DIRECTORY 0x00e0
#define LHD_LARGE 0x0100
#define LHD_UNICODE 0x0200
#define LHD_SALT 0x0400
#define LHD_EXTTIME 0x1000
#define LONG_BLOCK 0x8000
enum HEADER_TYPE {
MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74,COMM_HEAD=0x75,AV_HEAD=0x76,
SUB_HEAD=0x77,PROTECT_HEAD=0x78,SIGN_HEAD=0x79,NEWSUB_HEAD=0x7a,
ENDARC_HEAD=0x7b
};
enum HOST_SYSTEM {
HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
HOST_BEOS=5,HOST_MAX
};
struct OldMainHeader
{
byte Mark[4];
ushort HeadSize;
byte Flags;
};
struct OldFileHeader
{
uint PackSize;
uint UnpSize;
ushort FileCRC;
ushort HeadSize;
uint FileTime;
byte FileAttr;
byte Flags;
byte UnpVer;
byte NameSize;
byte Method;
};
struct MarkHeader
{
byte Mark[7];
};
struct BaseBlock
{
ushort HeadCRC;
HEADER_TYPE HeadType;//byte
ushort Flags;
ushort HeadSize;
};
struct BlockHeader:BaseBlock
{
union {
uint DataSize;
uint PackSize;
};
};
struct MainHeader:BlockHeader
{
ushort HighPosAV;
uint PosAV;
};
#define SALT_SIZE 8
struct FileHeader:BlockHeader
{
uint UnpSize;
byte HostOS;
uint FileCRC;
uint FileTime;
byte UnpVer;
byte Method;
ushort NameSize;
union {
uint FileAttr;
uint SubFlags;
};
uint HighPackSize;
uint HighUnpSize;
char FileName[NM];
Rar_Array<byte> SubData;
byte Salt[SALT_SIZE];
Int64 FullPackSize;
Int64 FullUnpSize;
FileHeader( Rar_Error_Handler* eh ) : SubData( eh ) { }
};
#endif

View File

@ -1,624 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
/****************************************************************************
* This file is part of PPMd project *
* Written and distributed to public domain by Dmitry Shkarin 1997, *
* 1999-2000 *
* Contents: model description and encoding/decoding routines *
****************************************************************************/
#include "rar.hpp"
#include "suballoc_inl.h"
inline void RangeCoder::InitDecoder(Unpack *UnpackRead)
{
RangeCoder::UnpackRead=UnpackRead;
low=code=0;
range=uint(-1);
for (int i=0;i < 4;i++)
code=(code << 8) | GetChar();
}
inline unsigned int RangeCoder::GetChar() {
return(UnpackRead->GetChar());
}
inline int RangeCoder::GetCurrentCount() {
return (code-low)/(range /= SubRange.scale);
}
inline uint RangeCoder::GetCurrentShiftCount(uint SHIFT) {
return (code-low)/(range >>= SHIFT);
}
inline void RangeCoder::Decode() {
low += range*SubRange.LowCount;
range *= SubRange.HighCount-SubRange.LowCount;
}
const uint TOP = 1 << 24;
const uint BOT = 1 << 15;
#define ARI_DEC_NORMALIZE(code,low,range,read) \
{ \
while ((low^(low+range))<TOP || range<BOT && ((range=-low&(BOT-1)),1)) \
{ \
code=(code << 8) | read->GetChar(); \
range <<= 8; \
low <<= 8; \
} \
}
inline PPM_CONTEXT* PPM_CONTEXT::createChild(ModelPPM *Model,STATE* pStats,
STATE& FirstState)
{
PPM_CONTEXT* pc = (PPM_CONTEXT*) Model->SubAlloc.AllocContext();
if ( pc )
{
pc->NumStats=1;
pc->OneState=FirstState;
pc->Suffix=this;
pStats->Successor=pc;
}
return pc;
}
ModelPPM::ModelPPM( Rar_Error_Handler* eh ) : SubAlloc( eh )
{
MinContext=NULL;
MaxContext=NULL;
MedContext=NULL;
MaxMB = 0;
}
void ModelPPM::RestartModelRare()
{
int i, k, m;
memset(CharMask,0,sizeof(CharMask));
SubAlloc.InitSubAllocator();
InitRL=-(MaxOrder < 12 ? MaxOrder:12)-1;
MinContext = MaxContext = (PPM_CONTEXT*) SubAlloc.AllocContext();
MinContext->Suffix=NULL;
OrderFall=MaxOrder;
MinContext->U.SummFreq=(MinContext->NumStats=256)+1;
FoundState=MinContext->U.Stats=(STATE*)SubAlloc.AllocUnits(256/2);
for (RunLength=InitRL, PrevSuccess=i=0;i < 256;i++)
{
MinContext->U.Stats[i].Symbol=i;
MinContext->U.Stats[i].Freq=1;
MinContext->U.Stats[i].Successor=NULL;
}
static const ushort InitBinEsc[]={
0x3CDD,0x1F3F,0x59BF,0x48F3,0x64A1,0x5ABC,0x6632,0x6051
};
for (i=0;i < 128;i++)
for (k=0;k < 8;k++)
for (m=0;m < 64;m += 8)
BinSumm[i][k+m]=BIN_SCALE-InitBinEsc[k]/(i+2);
for (i=0;i < 25;i++)
for (k=0;k < 16;k++)
SEE2Cont[i][k].init(5*i+10);
}
void ModelPPM::StartModelRare(int MaxOrder)
{
int i, k, m ,Step;
EscCount=1;
/*
if (MaxOrder < 2)
{
memset(CharMask,0,sizeof(CharMask));
OrderFall=ModelPPM::MaxOrder;
MinContext=MaxContext;
while (MinContext->Suffix != NULL)
{
MinContext=MinContext->Suffix;
OrderFall--;
}
FoundState=MinContext->U.Stats;
MinContext=MaxContext;
}
else
*/
{
ModelPPM::MaxOrder=MaxOrder;
RestartModelRare();
NS2BSIndx[0]=2*0;
NS2BSIndx[1]=2*1;
memset(NS2BSIndx+2,2*2,9);
memset(NS2BSIndx+11,2*3,256-11);
for (i=0;i < 3;i++)
NS2Indx[i]=i;
for (m=i, k=Step=1;i < 256;i++)
{
NS2Indx[i]=m;
if ( !--k )
{
k = ++Step;
m++;
}
}
memset(HB2Flag,0,0x40);
memset(HB2Flag+0x40,0x08,0x100-0x40);
DummySEE2Cont.Shift=PERIOD_BITS;
}
}
void PPM_CONTEXT::rescale(ModelPPM *Model)
{
int OldNS=NumStats, i=NumStats-1, Adder, EscFreq;
STATE* p1, * p;
for (p=Model->FoundState;p != U.Stats;p--)
_PPMD_SWAP(p[0],p[-1]);
U.Stats->Freq += 4;
U.SummFreq += 4;
EscFreq=U.SummFreq-p->Freq;
Adder=(Model->OrderFall != 0);
U.SummFreq = (p->Freq=(p->Freq+Adder) >> 1);
do
{
EscFreq -= (++p)->Freq;
U.SummFreq += (p->Freq=(p->Freq+Adder) >> 1);
if (p[0].Freq > p[-1].Freq)
{
STATE tmp=*(p1=p);
do
{
p1[0]=p1[-1];
} while (--p1 != U.Stats && tmp.Freq > p1[-1].Freq);
*p1=tmp;
}
} while ( --i );
if (p->Freq == 0)
{
do
{
i++;
} while ((--p)->Freq == 0);
EscFreq += i;
if ((NumStats -= i) == 1)
{
STATE tmp=*U.Stats;
do
{
tmp.Freq-=(tmp.Freq >> 1);
EscFreq>>=1;
} while (EscFreq > 1);
Model->SubAlloc.FreeUnits(U.Stats,(OldNS+1) >> 1);
*(Model->FoundState=&OneState)=tmp; return;
}
}
U.SummFreq += (EscFreq -= (EscFreq >> 1));
int n0=(OldNS+1) >> 1, n1=(NumStats+1) >> 1;
if (n0 != n1)
U.Stats = (STATE*) Model->SubAlloc.ShrinkUnits(U.Stats,n0,n1);
Model->FoundState=U.Stats;
}
inline PPM_CONTEXT* ModelPPM::CreateSuccessors(bool Skip,STATE* p1)
{
STATE UpState;
PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
STATE * p, * ps[MAX_O], ** pps=ps;
if ( !Skip )
{
*pps++ = FoundState;
if ( !pc->Suffix )
goto NO_LOOP;
}
if ( p1 )
{
p=p1;
pc=pc->Suffix;
goto LOOP_ENTRY;
}
do
{
pc=pc->Suffix;
if (pc->NumStats != 1)
{
if ((p=pc->U.Stats)->Symbol != FoundState->Symbol)
do
{
p++;
} while (p->Symbol != FoundState->Symbol);
}
else
p=&(pc->OneState);
LOOP_ENTRY:
if (p->Successor != UpBranch)
{
pc=p->Successor;
break;
}
*pps++ = p;
} while ( pc->Suffix );
NO_LOOP:
if (pps == ps)
return pc;
UpState.Symbol=*(byte*) UpBranch;
UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);
if (pc->NumStats != 1)
{
if ((byte*) pc <= SubAlloc.pText)
return(NULL);
if ((p=pc->U.Stats)->Symbol != UpState.Symbol)
do
{
p++;
} while (p->Symbol != UpState.Symbol);
uint cf=p->Freq-1;
uint s0=pc->U.SummFreq-pc->NumStats-cf;
UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
}
else
UpState.Freq=pc->OneState.Freq;
do
{
pc = pc->createChild(this,*--pps,UpState);
if ( !pc )
return NULL;
} while (pps != ps);
return pc;
}
inline void ModelPPM::UpdateModel()
{
STATE fs = *FoundState, *p = NULL;
PPM_CONTEXT *pc, *Successor;
uint ns1, ns, cf, sf, s0;
if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL)
{
if (pc->NumStats != 1)
{
if ((p=pc->U.Stats)->Symbol != fs.Symbol)
{
do
{
p++;
} while (p->Symbol != fs.Symbol);
if (p[0].Freq >= p[-1].Freq)
{
_PPMD_SWAP(p[0],p[-1]);
p--;
}
}
if (p->Freq < MAX_FREQ-9)
{
p->Freq += 2;
pc->U.SummFreq += 2;
}
}
else
{
p=&(pc->OneState);
p->Freq += (p->Freq < 32);
}
}
if ( !OrderFall )
{
MinContext=MaxContext=FoundState->Successor=CreateSuccessors(true,p);
if ( !MinContext )
goto RESTART_MODEL;
return;
}
*SubAlloc.pText++ = fs.Symbol;
Successor = (PPM_CONTEXT*) SubAlloc.pText;
if (SubAlloc.pText >= SubAlloc.FakeUnitsStart)
goto RESTART_MODEL;
if ( fs.Successor )
{
if ((byte*) fs.Successor <= SubAlloc.pText &&
(fs.Successor=CreateSuccessors(false,p)) == NULL)
goto RESTART_MODEL;
if ( !--OrderFall )
{
Successor=fs.Successor;
SubAlloc.pText -= (MaxContext != MinContext);
}
}
else
{
FoundState->Successor=Successor;
fs.Successor=MinContext;
}
s0=MinContext->U.SummFreq-(ns=MinContext->NumStats)-(fs.Freq-1);
for (pc=MaxContext;pc != MinContext;pc=pc->Suffix)
{
if ((ns1=pc->NumStats) != 1)
{
if ((ns1 & 1) == 0)
{
pc->U.Stats=(STATE*) SubAlloc.ExpandUnits(pc->U.Stats,ns1 >> 1);
if ( !pc->U.Stats )
goto RESTART_MODEL;
}
pc->U.SummFreq += (2*ns1 < ns)+2*((4*ns1 <= ns) & (pc->U.SummFreq <= 8*ns1));
}
else
{
p=(STATE*) SubAlloc.AllocUnits(1);
if ( !p )
goto RESTART_MODEL;
*p=pc->OneState;
pc->U.Stats=p;
if (p->Freq < MAX_FREQ/4-1)
p->Freq += p->Freq;
else
p->Freq = MAX_FREQ-4;
pc->U.SummFreq=p->Freq+InitEsc+(ns > 3);
}
cf=2*fs.Freq*(pc->U.SummFreq+6);
sf=s0+pc->U.SummFreq;
if (cf < 6*sf)
{
cf=1+(cf > sf)+(cf >= 4*sf);
pc->U.SummFreq += 3;
}
else
{
cf=4+(cf >= 9*sf)+(cf >= 12*sf)+(cf >= 15*sf);
pc->U.SummFreq += cf;
}
p=pc->U.Stats+ns1;
p->Successor=Successor;
p->Symbol = fs.Symbol;
p->Freq = cf;
pc->NumStats=++ns1;
}
MaxContext=MinContext=fs.Successor;
return;
RESTART_MODEL:
RestartModelRare();
EscCount=0;
}
// Tabulated escapes for exponential symbol distribution
static const byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT))
inline void PPM_CONTEXT::decodeBinSymbol(ModelPPM *Model)
{
STATE& rs=OneState;
Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
ushort& bs=Model->BinSumm[rs.Freq-1][Model->PrevSuccess+
Model->NS2BSIndx[Suffix->NumStats-1]+
Model->HiBitsFlag+2*Model->HB2Flag[rs.Symbol]+
((Model->RunLength >> 26) & 0x20)];
if (Model->Coder.GetCurrentShiftCount(TOT_BITS) < bs)
{
Model->FoundState=&rs;
rs.Freq += (rs.Freq < 128);
Model->Coder.SubRange.LowCount=0;
Model->Coder.SubRange.HighCount=bs;
bs = (bs+INTERVAL-GET_MEAN(bs,PERIOD_BITS,2)) & 0xFFFF;
Model->PrevSuccess=1;
Model->RunLength++;
}
else
{
Model->Coder.SubRange.LowCount=bs;
bs = (bs-GET_MEAN(bs,PERIOD_BITS,2)) & 0xFFFF;
Model->Coder.SubRange.HighCount=BIN_SCALE;
Model->InitEsc=ExpEscape[bs >> 10];
Model->NumMasked=1;
Model->CharMask[rs.Symbol]=Model->EscCount;
Model->PrevSuccess=0;
Model->FoundState=NULL;
}
}
inline void PPM_CONTEXT::update1(ModelPPM *Model,STATE* p)
{
(Model->FoundState=p)->Freq += 4;
U.SummFreq += 4;
if (p[0].Freq > p[-1].Freq)
{
_PPMD_SWAP(p[0],p[-1]);
Model->FoundState=--p;
if (p->Freq > MAX_FREQ)
rescale(Model);
}
}
inline bool PPM_CONTEXT::decodeSymbol1(ModelPPM *Model)
{
Model->Coder.SubRange.scale=U.SummFreq;
STATE* p=U.Stats;
int i, HiCnt;
int count=Model->Coder.GetCurrentCount();
if (count>=Model->Coder.SubRange.scale)
return(false);
if (count < (HiCnt=p->Freq))
{
Model->PrevSuccess=(2*(Model->Coder.SubRange.HighCount=HiCnt) > Model->Coder.SubRange.scale);
Model->RunLength += Model->PrevSuccess;
(Model->FoundState=p)->Freq=(HiCnt += 4);
U.SummFreq += 4;
if (HiCnt > MAX_FREQ)
rescale(Model);
Model->Coder.SubRange.LowCount=0;
return(true);
}
else
if (Model->FoundState==NULL)
return(false);
Model->PrevSuccess=0;
i=NumStats-1;
while ((HiCnt += (++p)->Freq) <= count)
if (--i == 0)
{
Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
Model->Coder.SubRange.LowCount=HiCnt;
Model->CharMask[p->Symbol]=Model->EscCount;
i=(Model->NumMasked=NumStats)-1;
Model->FoundState=NULL;
do
{
Model->CharMask[(--p)->Symbol]=Model->EscCount;
} while ( --i );
Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
return(true);
}
Model->Coder.SubRange.LowCount=(Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
update1(Model,p);
return(true);
}
inline void PPM_CONTEXT::update2(ModelPPM *Model,STATE* p)
{
(Model->FoundState=p)->Freq += 4;
U.SummFreq += 4;
if (p->Freq > MAX_FREQ)
rescale(Model);
Model->EscCount++;
Model->RunLength=Model->InitRL;
}
inline SEE2_CONTEXT* PPM_CONTEXT::makeEscFreq2(ModelPPM *Model,int Diff)
{
SEE2_CONTEXT* psee2c;
if (NumStats != 256)
{
psee2c=Model->SEE2Cont[Model->NS2Indx[Diff-1]]+
(Diff < Suffix->NumStats-NumStats)+
2*(U.SummFreq < 11*NumStats)+4*(Model->NumMasked > Diff)+
Model->HiBitsFlag;
Model->Coder.SubRange.scale=psee2c->getMean();
}
else
{
psee2c=&Model->DummySEE2Cont;
Model->Coder.SubRange.scale=1;
}
return psee2c;
}
inline bool PPM_CONTEXT::decodeSymbol2(ModelPPM *Model)
{
int count, HiCnt, i=NumStats-Model->NumMasked;
SEE2_CONTEXT* psee2c=makeEscFreq2(Model,i);
STATE* ps[256], ** pps=ps, * p=U.Stats-1;
HiCnt=0;
do
{
do
{
p++;
} while (Model->CharMask[p->Symbol] == Model->EscCount);
HiCnt += p->Freq;
*pps++ = p;
} while ( --i );
Model->Coder.SubRange.scale += HiCnt;
count=Model->Coder.GetCurrentCount();
if (count>=Model->Coder.SubRange.scale)
return(false);
p=*(pps=ps);
if (count < HiCnt)
{
HiCnt=0;
while ((HiCnt += p->Freq) <= count)
p=*++pps;
Model->Coder.SubRange.LowCount = (Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
psee2c->update();
update2(Model,p);
}
else
{
Model->Coder.SubRange.LowCount=HiCnt;
Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
i=NumStats-Model->NumMasked;
pps--;
do
{
Model->CharMask[(*++pps)->Symbol]=Model->EscCount;
} while ( --i );
psee2c->Summ += Model->Coder.SubRange.scale;
Model->NumMasked = NumStats;
}
return(true);
}
inline void ModelPPM::ClearMask()
{
EscCount=1;
memset(CharMask,0,sizeof(CharMask));
}
bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar )
{
int MaxOrder=UnpackRead->GetChar();
bool Reset=MaxOrder & 0x20;
if (Reset)
MaxMB = UnpackRead->GetChar() + 1;
else
if (SubAlloc.GetAllocatedMemory()==0)
return(false);
if (MaxOrder & 0x40)
EscChar=UnpackRead->GetChar();
Coder.InitDecoder(UnpackRead);
if (Reset)
{
MaxOrder=(MaxOrder & 0x1f)+1;
if (MaxOrder>16)
MaxOrder=16+(MaxOrder-16)*3;
if (MaxOrder==1)
{
SubAlloc.StopSubAllocator();
return(false);
}
SubAlloc.StartSubAllocator(MaxMB);
StartModelRare(MaxOrder);
}
return(MinContext!=NULL);
}
int ModelPPM::DecodeChar()
{
if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
return(-1);
if (MinContext->NumStats != 1)
{
if ((byte*)MinContext->U.Stats <= SubAlloc.pText || (byte*)MinContext->U.Stats>SubAlloc.HeapEnd)
return(-1);
if (!MinContext->decodeSymbol1(this))
return(-1);
}
else
MinContext->decodeBinSymbol(this);
Coder.Decode();
while ( !FoundState )
{
ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
do
{
OrderFall++;
MinContext=MinContext->Suffix;
if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
return(-1);
} while (MinContext->NumStats == NumMasked);
if (!MinContext->decodeSymbol2(this))
return(-1);
Coder.Decode();
}
int Symbol=FoundState->Symbol;
if (!OrderFall && (byte*) FoundState->Successor > SubAlloc.pText)
MinContext=MaxContext=FoundState->Successor;
else
{
UpdateModel();
if (EscCount == 0)
ClearMask();
}
ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
return(Symbol);
}

View File

@ -1,143 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#ifndef _RAR_PPMMODEL_
#define _RAR_PPMMODEL_
const int MAX_O=64; /* maximum allowed model order */
const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124;
#pragma pack(1)
struct _PACK_ATTR SEE2_CONTEXT
{ // SEE-contexts for PPM-contexts with masked symbols
ushort Summ;
byte Shift, Count;
void init(int InitVal)
{
Summ=InitVal << (Shift=PERIOD_BITS-4);
Count=4;
}
uint getMean()
{
uint RetVal=(Summ & 0xFFFF) >> Shift;
Summ -= RetVal;
return RetVal+(RetVal == 0);
}
void update()
{
if (Shift < PERIOD_BITS && --Count == 0)
{
Summ += Summ;
Count=3 << Shift++;
}
}
};
class ModelPPM;
struct PPM_CONTEXT;
struct _PACK_ATTR STATE
{
byte Symbol;
byte Freq;
PPM_CONTEXT* Successor;
};
struct _PACK_ATTR FreqData
{
ushort SummFreq;
STATE* Stats;
};
struct PPM_CONTEXT
{
ushort NumStats;
union
{
FreqData U;
STATE OneState;
};
PPM_CONTEXT* Suffix;
inline void encodeBinSymbol(ModelPPM *Model,int symbol); // MaxOrder:
inline void encodeSymbol1(ModelPPM *Model,int symbol); // ABCD context
inline void encodeSymbol2(ModelPPM *Model,int symbol); // BCD suffix
inline void decodeBinSymbol(ModelPPM *Model); // BCDE successor
inline bool decodeSymbol1(ModelPPM *Model); // other orders:
inline bool decodeSymbol2(ModelPPM *Model); // BCD context
inline void update1(ModelPPM *Model,STATE* p); // CD suffix
inline void update2(ModelPPM *Model,STATE* p); // BCDE successor
void rescale(ModelPPM *Model);
inline PPM_CONTEXT* createChild(ModelPPM *Model,STATE* pStats,STATE& FirstState);
inline SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff);
};
#pragma pack()
#define Max( x, y ) ((x) < (y) ? (y) : (x))
const uint UNIT_SIZE=Max(sizeof(PPM_CONTEXT),sizeof(RAR_MEM_BLK));
const uint FIXED_UNIT_SIZE=12;
/*
inline PPM_CONTEXT::PPM_CONTEXT(STATE* pStats,PPM_CONTEXT* ShorterContext):
NumStats(1), Suffix(ShorterContext) { pStats->Successor=this; }
inline PPM_CONTEXT::PPM_CONTEXT(): NumStats(0) {}
*/
inline void _PPMD_SWAP( STATE& t1,STATE& t2) { STATE tmp=t1; t1=t2; t2=tmp; }
// 'Carryless rangecoder' by Dmitry Subbotin
class RangeCoder {
public:
void InitDecoder(Unpack *UnpackRead);
inline int GetCurrentCount();
inline uint GetCurrentShiftCount(uint SHIFT);
inline void Decode();
inline void PutChar(unsigned int c);
inline unsigned int GetChar();
uint low, code, range;
struct SUBRANGE
{
uint LowCount, HighCount, scale;
} SubRange;
Unpack *UnpackRead;
};
class ModelPPM
{
private:
friend struct PPM_CONTEXT;
SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
struct PPM_CONTEXT *MinContext, *MedContext, *MaxContext;
STATE* FoundState; // found next state transition
int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL;
byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
byte EscCount, PrevSuccess, HiBitsFlag;
ushort BinSumm[128][64]; // binary SEE-contexts
RangeCoder Coder;
SubAllocator SubAlloc;
void RestartModelRare();
void StartModelRare(int MaxOrder);
inline PPM_CONTEXT* CreateSuccessors(bool Skip,STATE* p1);
inline void UpdateModel();
inline void ClearMask();
public:
int MaxMB; // mega memory allocation size, for informational purposes only
ModelPPM( Rar_Error_Handler* );
bool DecodeInit(Unpack *UnpackRead,int &EscChar);
int DecodeChar();
};
#endif

View File

@ -1,60 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#ifndef RAR_COMMON_HPP
#define RAR_COMMON_HPP
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
const int NM = 1024; // max filename length
typedef unsigned char byte;
typedef unsigned short ushort;
typedef unsigned int uint;
#define Min( x, y ) ((x) < (y) ? (x) : (y))
// 64-bit int support disabled, since this library isn't meant for huge 2GB+ archives
typedef long Int64;
#define int64to32(x) ((uint)(x))
#ifdef __GNUC__
#define _PACK_ATTR __attribute__ ((packed))
#else
#define _PACK_ATTR
#endif
// used as base class to override new and delete to not throw exceptions
struct Rar_Allocator
{
// throw spec mandatory in ISO C++ if operator new can return NULL
#if __cplusplus >= 199711 || __GNUC__ >= 3
void* operator new ( size_t s ) throw () { return malloc( s ); }
#else
void* operator new ( size_t s ) { return malloc( s ); }
#endif
void operator delete ( void* p ) { free( p ); }
};
class Rar_Extractor_Impl;
typedef Rar_Extractor_Impl Rar_Error_Handler;
void rar_out_of_memory( Rar_Error_Handler* );
// lots of order dependencies here
class Unpack;
#include "rarmisc.hpp"
#include "array.hpp"
#include "headers.hpp"
#include "archive.hpp"
#include "rarvm.hpp"
#include "suballoc.hpp"
#include "model.hpp"
#include "unpack.hpp"
#include "Rar_Extractor_Impl.h"
#endif

View File

@ -1,70 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#include "rar.hpp"
// CRC
static uint CRCTab [256];
void InitCRC()
{
if ( !CRCTab [1] )
{
for ( int i = 256; --i >= 0; )
{
unsigned c = i;
for ( int n = 8; --n >= 0; )
c = (c >> 1) ^ (0xEDB88320L & -(c & 1));
CRCTab [i] = c;
}
}
}
uint CRC( uint crc, void const* in, uint count )
{
byte const* p = (byte const*) in;
byte const* end = (byte const*) in + count;
while ( p < end )
crc = (crc >> 8) ^ CRCTab [(crc & 0xFF) ^ *p++];
return crc;
}
ushort OldCRC( ushort crc, void const* in, uint count )
{
byte const* p = (byte const*) in;
byte const* end = p + count;
while ( p < end )
{
crc += *p++;
crc = (crc << 1) | (crc >> 15 & 1);
}
return crc & 0xFFFF;
}
// BitInput
BitInput::BitInput( Rar_Error_Handler* eh )
{
error_handler = eh;
InBuf = (byte*) malloc( MAX_SIZE );
if ( !InBuf )
rar_out_of_memory( error_handler );
}
BitInput::~BitInput()
{
free( InBuf );
}
void BitInput::faddbits(int Bits)
{
addbits( Bits );
}
unsigned int BitInput::fgetbits()
{
return getbits();
}

View File

@ -1,65 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#ifndef _RAR_RARMISC_
#define _RAR_RARMISC_
void InitCRC();
uint CRC( uint crc, void const* in, uint count );
ushort OldCRC( ushort crc, void const* in, uint count );
class BitInput {
public:
enum { MAX_SIZE = 0x8000 };
protected:
int InAddr, InBit;
Rar_Error_Handler* error_handler;
public:
BitInput( Rar_Error_Handler* eh );
~BitInput();
byte* InBuf;
void InitBitInput()
{
InAddr = InBit = 0;
}
void addbits( int Bits )
{
Bits += InBit;
InAddr += Bits >> 3;
InBit = Bits & 7;
}
unsigned int getbits()
{
unsigned int BitField = (uint) InBuf [InAddr] << 16;
BitField |= (uint) InBuf [InAddr + 1] << 8;
BitField |= (uint) InBuf [InAddr + 2];
BitField >>= (8 - InBit);
return BitField & 0xFFFF;
}
void faddbits( int Bits );
unsigned int fgetbits();
};
#define MAXWINSIZE 0x400000
#define MAXWINMASK (MAXWINSIZE-1)
#define LOW_DIST_REP_COUNT 16
#define NC 299 /* alphabet = {0, 1, 2, ..., NC - 1} */
#define DC 60
#define LDC 17
#define RC 28
#define HUFF_TABLE_SIZE (NC+DC+RC+LDC)
#define BC 20
#define NC20 298 /* alphabet = {0, 1, 2, ..., NC - 1} */
#define DC20 48
#define RC20 28
#define BC20 19
#define MC20 257
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,116 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#ifndef _RAR_VM_
#define _RAR_VM_
#define VM_STANDARDFILTERS
#define VM_OPTIMIZE
#define VM_MEMSIZE 0x40000
#define VM_MEMMASK (VM_MEMSIZE-1)
#define VM_GLOBALMEMADDR 0x3C000
#define VM_GLOBALMEMSIZE 0x2000
#define VM_FIXEDGLOBALSIZE 64
enum VM_Commands
{
VM_MOV, VM_CMP, VM_ADD, VM_SUB, VM_JZ, VM_JNZ, VM_INC, VM_DEC,
VM_JMP, VM_XOR, VM_AND, VM_OR, VM_TEST, VM_JS, VM_JNS, VM_JB,
VM_JBE, VM_JA, VM_JAE, VM_PUSH, VM_POP, VM_CALL, VM_RET, VM_NOT,
VM_SHL, VM_SHR, VM_SAR, VM_NEG, VM_PUSHA,VM_POPA, VM_PUSHF,VM_POPF,
VM_MOVZX,VM_MOVSX,VM_XCHG, VM_MUL, VM_DIV, VM_ADC, VM_SBB, VM_PRINT,
#ifdef VM_OPTIMIZE
VM_MOVB, VM_MOVD, VM_CMPB, VM_CMPD,
VM_ADDB, VM_ADDD, VM_SUBB, VM_SUBD, VM_INCB, VM_INCD, VM_DECB, VM_DECD,
VM_NEGB, VM_NEGD,
#endif
VM_STANDARD
};
enum VM_StandardFilters {
VMSF_NONE, VMSF_E8, VMSF_E8E9, VMSF_ITANIUM, VMSF_RGB, VMSF_AUDIO,
VMSF_DELTA, VMSF_UPCASE
};
enum VM_Flags {VM_FC=1,VM_FZ=2,VM_FS=0x80000000};
enum VM_OpType {VM_OPREG,VM_OPINT,VM_OPREGMEM,VM_OPNONE};
struct VM_PreparedOperand
{
VM_OpType Type;
uint Data;
uint Base;
uint *Addr;
};
struct VM_PreparedCommand
{
VM_Commands OpCode;
bool ByteMode;
VM_PreparedOperand Op1,Op2;
};
struct VM_PreparedProgram
{
VM_PreparedProgram( Rar_Error_Handler* eh ) : Cmd( eh ), GlobalData( eh ), StaticData( eh )
{
AltCmd = NULL;
}
Rar_Array<VM_PreparedCommand> Cmd;
VM_PreparedCommand *AltCmd;
int CmdCount;
Rar_Array<byte> GlobalData;
Rar_Array<byte> StaticData;
uint InitR[7];
byte *FilteredData;
unsigned int FilteredDataSize;
};
class RarVM : private BitInput
{
private:
inline uint GetValue(bool ByteMode,uint *Addr);
inline void SetValue(bool ByteMode,uint *Addr,uint Value);
inline uint* GetOperand(VM_PreparedOperand *CmdOp);
void PrintState(uint IP);
void DecodeArg(VM_PreparedOperand &Op,bool ByteMode);
#ifdef VM_OPTIMIZE
void Optimize(VM_PreparedProgram *Prg);
#endif
bool ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize);
#ifdef VM_STANDARDFILTERS
VM_StandardFilters IsStandardFilter(byte *Code,int CodeSize);
void ExecuteStandardFilter(VM_StandardFilters FilterType);
unsigned int FilterItanium_GetBits(byte *Data,int BitPos,int BitCount);
void FilterItanium_SetBits(byte *Data,unsigned int BitField,int BitPos,
int BitCount);
#endif
byte *Mem;
uint R[8];
uint Flags;
Rar_Error_Handler* error_handler;
public:
RarVM( Rar_Error_Handler* );
~RarVM();
void Init();
void Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg);
void Execute(VM_PreparedProgram *Prg);
void SetValue(uint *Addr,uint Value);
void SetMemory(unsigned int Pos,byte *Data,unsigned int DataSize);
static uint ReadData(BitInput &Inp);
};
#endif

View File

@ -1,24 +0,0 @@
This library is based on UnRAR (unrarsrc-3.6.8.tar.gz) by Alexander L.
Roshal. The original sources have been heavily modified, trimmed down,
and purged of all OS-specific calls for file access and other
unnecessary operations. Refer to unrar_license.txt for full licensing
terms. The original unRAR source is available at http://www.rarlab.com/
It is important to provide 1 byte alignment for structures in model.hpp.
Now it contains '#pragma pack(1)' directive, but your compiler may
require something else. Though Unrar should work with other model.hpp
alignments, its memory requirements may increase significantly.
Alignment in other modules is not important.
Dmitry Shkarin wrote PPMII text compression. Dmitry Subbotin wrote the
carryless rangecoder.
Unrar source may be used in any software to handle RAR archives without
limitations free of charge, but cannot be used to re-create the RAR
compression algorithm, which is proprietary. Distribution of modified
Unrar source in separate form or as a part of other software is
permitted, provided that it is clearly stated in the documentation and
source comments that the code may not be used to develop a RAR (WinRAR)
compatible archiver.
--
Shay Green <gblargg@gmail.com>

View File

@ -1,158 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
/****************************************************************************
* This file is part of PPMd project *
* Written and distributed to public domain by Dmitry Shkarin 1997, *
* 1999-2000 *
* Contents: memory allocation routines *
****************************************************************************/
#include "rar.hpp"
#include "suballoc_inl.h"
SubAllocator::SubAllocator( Rar_Error_Handler* eh )
{
error_handler = eh;
Clean();
}
void SubAllocator::Clean()
{
SubAllocatorSize=0;
}
void SubAllocator::StopSubAllocator()
{
if ( SubAllocatorSize )
{
SubAllocatorSize=0;
free( HeapStart );
HeapStart = NULL;
}
}
bool SubAllocator::StartSubAllocator(int SASize)
{
uint t=SASize << 20;
if (SubAllocatorSize == t)
return true;
StopSubAllocator();
uint AllocSize=t/FIXED_UNIT_SIZE*UNIT_SIZE+UNIT_SIZE;
HeapStart = (byte*) malloc( AllocSize );
if ( !HeapStart )
rar_out_of_memory( error_handler );
HeapEnd=HeapStart+AllocSize-UNIT_SIZE;
SubAllocatorSize=t;
return true;
}
void SubAllocator::InitSubAllocator()
{
int i, k;
memset(FreeList,0,sizeof(FreeList));
pText=HeapStart;
uint Size2=FIXED_UNIT_SIZE*(SubAllocatorSize/8/FIXED_UNIT_SIZE*7);
uint RealSize2=Size2/FIXED_UNIT_SIZE*UNIT_SIZE;
uint Size1=SubAllocatorSize-Size2;
uint RealSize1=Size1/FIXED_UNIT_SIZE*UNIT_SIZE+Size1%FIXED_UNIT_SIZE;
HiUnit=HeapStart+SubAllocatorSize;
LoUnit=UnitsStart=HeapStart+RealSize1;
FakeUnitsStart=HeapStart+Size1;
HiUnit=LoUnit+RealSize2;
for (i=0,k=1;i < N1 ;i++,k += 1)
Indx2Units[i]=k;
for (k++;i < N1+N2 ;i++,k += 2)
Indx2Units[i]=k;
for (k++;i < N1+N2+N3 ;i++,k += 3)
Indx2Units[i]=k;
for (k++;i < N1+N2+N3+N4;i++,k += 4)
Indx2Units[i]=k;
for (GlueCount=k=i=0;k < 128;k++)
{
i += (Indx2Units[i] < k+1);
Units2Indx[k]=i;
}
}
void* SubAllocator::AllocUnitsRare(int indx)
{
if ( !GlueCount )
{
GlueCount = 255;
GlueFreeBlocks();
if ( FreeList[indx].next )
return RemoveNode(indx);
}
int i=indx;
do
{
if (++i == N_INDEXES)
{
GlueCount--;
i=U2B(Indx2Units[indx]);
int j=12*Indx2Units[indx];
if (FakeUnitsStart-pText > j)
{
FakeUnitsStart-=j;
UnitsStart -= i;
return(UnitsStart);
}
return(NULL);
}
} while ( !FreeList[i].next );
void* RetVal=RemoveNode(i);
SplitBlock(RetVal,i,indx);
return RetVal;
}
void* SubAllocator::AllocContext()
{
if (HiUnit != LoUnit)
return (HiUnit -= UNIT_SIZE);
if ( FreeList->next )
return RemoveNode(0);
return AllocUnitsRare(0);
}
void* SubAllocator::ExpandUnits(void* OldPtr,int OldNU)
{
int i0=Units2Indx[OldNU-1], i1=Units2Indx[OldNU-1+1];
if (i0 == i1)
return OldPtr;
void* ptr=AllocUnits(OldNU+1);
if ( ptr )
{
memcpy(ptr,OldPtr,U2B(OldNU));
InsertNode(OldPtr,i0);
}
return ptr;
}
void* SubAllocator::ShrinkUnits(void* OldPtr,int OldNU,int NewNU)
{
int i0=Units2Indx[OldNU-1], i1=Units2Indx[NewNU-1];
if (i0 == i1)
return OldPtr;
if ( FreeList[i1].next )
{
void* ptr=RemoveNode(i1);
memcpy(ptr,OldPtr,U2B(NewNU));
InsertNode(OldPtr,i0);
return ptr;
}
else
{
SplitBlock(OldPtr,i0,i1);
return OldPtr;
}
}
void SubAllocator::FreeUnits(void* ptr,int OldNU)
{
InsertNode(ptr,Units2Indx[OldNU-1]);
}

View File

@ -1,74 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
/****************************************************************************
* This file is part of PPMd project *
* Written and distributed to public domain by Dmitry Shkarin 1997, *
* 1999-2000 *
* Contents: interface to memory allocation routines *
****************************************************************************/
#ifndef _SUBALLOC_H_
#define _SUBALLOC_H_
const int N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4;
const int N_INDEXES=N1+N2+N3+N4;
#pragma pack(1)
struct _PACK_ATTR RAR_MEM_BLK
{
ushort Stamp, NU;
RAR_MEM_BLK* next, * prev;
void insertAt(RAR_MEM_BLK* p)
{
next=(prev=p)->next;
p->next=next->prev=this;
}
void remove()
{
prev->next=next;
next->prev=prev;
}
};
#pragma pack()
struct RAR_NODE
{
RAR_NODE* next;
};
class SubAllocator
{
private:
void InsertNode(void* p,int indx);
void* RemoveNode(int indx);
uint U2B(int NU);
void SplitBlock(void* pv,int OldIndx,int NewIndx);
uint GetUsedMemory();
void GlueFreeBlocks();
void* AllocUnitsRare(int indx);
long SubAllocatorSize;
byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;
byte *HeapStart,*LoUnit, *HiUnit;
struct RAR_NODE FreeList[N_INDEXES];
Rar_Error_Handler* error_handler;
public:
SubAllocator( Rar_Error_Handler* );
~SubAllocator() {StopSubAllocator();}
void Clean();
bool StartSubAllocator(int SASize);
void StopSubAllocator();
void InitSubAllocator();
void* AllocContext();
void* AllocUnits(int NU);
void* ExpandUnits(void* ptr,int OldNU);
void* ShrinkUnits(void* ptr,int OldNU,int NewNU);
void FreeUnits(void* ptr,int OldNU);
long GetAllocatedMemory() {return(SubAllocatorSize);};
byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart;
};
#endif /* !defined(_SUBALLOC_H_) */

View File

@ -1,88 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
/****************************************************************************
* This file is part of PPMd project *
* Written and distributed to public domain by Dmitry Shkarin 1997, *
* 1999-2000 *
* Contents: interface to memory allocation routines *
****************************************************************************/
inline uint SubAllocator::U2B(int NU)
{
return /*8*NU+4*NU*/UNIT_SIZE*NU;
}
inline void* SubAllocator::RemoveNode(int indx)
{
RAR_NODE* RetVal=FreeList[indx].next;
FreeList[indx].next=RetVal->next;
return RetVal;
}
inline void* SubAllocator::AllocUnits(int NU)
{
int indx=Units2Indx[NU-1];
if ( FreeList[indx].next )
return RemoveNode(indx);
void* RetVal=LoUnit;
LoUnit += U2B(Indx2Units[indx]);
if (LoUnit <= HiUnit)
return RetVal;
LoUnit -= U2B(Indx2Units[indx]);
return AllocUnitsRare(indx);
}
inline void SubAllocator::InsertNode(void* p,int indx)
{
((RAR_NODE*) p)->next=FreeList[indx].next;
FreeList[indx].next=(RAR_NODE*) p;
}
inline void SubAllocator::SplitBlock(void* pv,int OldIndx,int NewIndx)
{
int i, UDiff=Indx2Units[OldIndx]-Indx2Units[NewIndx];
byte* p=((byte*) pv)+U2B(Indx2Units[NewIndx]);
if (Indx2Units[i=Units2Indx[UDiff-1]] != UDiff)
{
InsertNode(p,--i);
p += U2B(i=Indx2Units[i]);
UDiff -= i;
}
InsertNode(p,Units2Indx[UDiff-1]);
}
inline void SubAllocator::GlueFreeBlocks()
{
RAR_MEM_BLK s0, * p, * p1;
int i, k, sz;
if (LoUnit != HiUnit)
*LoUnit=0;
for (i=0, s0.next=s0.prev=&s0;i < N_INDEXES;i++)
while ( FreeList[i].next )
{
p=(RAR_MEM_BLK*)RemoveNode(i);
p->insertAt(&s0);
p->Stamp=0xFFFF;
p->NU=Indx2Units[i];
}
for (p=s0.next;p != &s0;p=p->next)
while ((p1=p+p->NU)->Stamp == 0xFFFF && int(p->NU)+p1->NU < 0x10000)
{
p1->remove();
p->NU += p1->NU;
}
while ((p=s0.next) != &s0)
{
for (p->remove(), sz=p->NU;sz > 128;sz -= 128, p += 128)
InsertNode(p,N_INDEXES-1);
if (Indx2Units[i=Units2Indx[sz-1]] != sz)
{
k=sz-Indx2Units[--i];
InsertNode(p+(sz-k),k-1);
}
InsertNode(p,i);
}
}

View File

@ -1,918 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#include "rar.hpp"
#if defined (__MWERKS__) && __MWERKS__ < 0x3200
// higher level breaks code in CW4 (but not in CW9)
#pragma optimization_level 1
#endif
Unpack::Unpack( Rar_Extractor_Impl *DataIO, Rar_Error_Handler* eh ) :
BitInput( eh ), VMCode( eh ), Inp( eh ), PPM( eh ), VM( eh ),
Filters( eh ), PrgStack( eh ), OldFilterLengths( eh )
{
error_handler = eh;
UnpIO=DataIO;
Window=NULL;
ExternalWindow=false;
Suspended=false;
UnpAllBuf=false;
UnpSomeRead=false;
}
Unpack::~Unpack()
{
if (Window!=NULL && !ExternalWindow)
free( Window );
InitFilters();
}
void Unpack::Init(byte *Window)
{
if (Window==NULL)
{
Unpack::Window = (byte*) malloc( MAXWINSIZE );
if ( !Unpack::Window )
rar_out_of_memory( error_handler );
}
else
{
Unpack::Window=Window;
ExternalWindow=true;
}
UnpInitData(false);
}
void Unpack::DoUnpack(int Method,bool Solid)
{
switch(Method)
{
case 15: // rar 1.5 compression
Unpack15(Solid);
break;
case 20: // rar 2.x compression
case 26: // files larger than 2GB
Unpack20(Solid);
break;
case 29: // rar 3.x compression
Unpack29(Solid);
break;
}
}
inline void Unpack::InsertOldDist(unsigned int Distance)
{
OldDist[3]=OldDist[2];
OldDist[2]=OldDist[1];
OldDist[1]=OldDist[0];
OldDist[0]=Distance;
}
inline void Unpack::InsertLastMatch(unsigned int Length,unsigned int Distance)
{
LastDist=Distance;
LastLength=Length;
}
void Unpack::CopyString(unsigned int Length,unsigned int Distance)
{
unsigned int DestPtr=UnpPtr-Distance;
if (DestPtr<MAXWINSIZE-260 && UnpPtr<MAXWINSIZE-260)
{
Window[UnpPtr++]=Window[DestPtr++];
while (--Length>0)
Window[UnpPtr++]=Window[DestPtr++];
}
else
while (Length--)
{
Window[UnpPtr]=Window[DestPtr++ & MAXWINMASK];
UnpPtr=(UnpPtr+1) & MAXWINMASK;
}
}
int Unpack::DecodeNumber(struct Decode *Dec)
{
unsigned int Bits;
unsigned int BitField=getbits() & 0xfffe;
if (BitField<Dec->DecodeLen[8])
if (BitField<Dec->DecodeLen[4])
if (BitField<Dec->DecodeLen[2])
if (BitField<Dec->DecodeLen[1])
Bits=1;
else
Bits=2;
else
if (BitField<Dec->DecodeLen[3])
Bits=3;
else
Bits=4;
else
if (BitField<Dec->DecodeLen[6])
if (BitField<Dec->DecodeLen[5])
Bits=5;
else
Bits=6;
else
if (BitField<Dec->DecodeLen[7])
Bits=7;
else
Bits=8;
else
if (BitField<Dec->DecodeLen[12])
if (BitField<Dec->DecodeLen[10])
if (BitField<Dec->DecodeLen[9])
Bits=9;
else
Bits=10;
else
if (BitField<Dec->DecodeLen[11])
Bits=11;
else
Bits=12;
else
if (BitField<Dec->DecodeLen[14])
if (BitField<Dec->DecodeLen[13])
Bits=13;
else
Bits=14;
else
Bits=15;
addbits(Bits);
unsigned int N=Dec->DecodePos[Bits]+((BitField-Dec->DecodeLen[Bits-1])>>(16-Bits));
if (N>=Dec->MaxNum)
N=0;
return(Dec->DecodeNum[N]);
}
void Unpack::Unpack29(bool Solid)
{
static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
static int DDecode[DC];
static byte DBits[DC];
static int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12};
static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6};
unsigned int Bits;
if (DDecode[1]==0)
{
int Dist=0,BitLength=0,Slot=0;
for (int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++)
for (int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength))
{
DDecode[Slot]=Dist;
DBits[Slot]=BitLength;
}
}
FileExtracted=true;
if (!Suspended)
{
UnpInitData(Solid);
if (!UnpReadBuf())
return;
if ((!Solid || !TablesRead) && !ReadTables())
return;
}
if (PPMError)
return;
while (true)
{
UnpPtr&=MAXWINMASK;
if (InAddr>ReadBorder)
{
if (!UnpReadBuf())
break;
}
if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr)
{
UnpWriteBuf();
if (WrittenFileSize>DestUnpSize)
return;
if (Suspended)
{
FileExtracted=false;
return;
}
}
if (UnpBlockType==BLOCK_PPM)
{
int Ch=PPM.DecodeChar();
if (Ch==-1)
{
PPMError=true;
break;
}
if (Ch==PPMEscChar)
{
int NextCh=PPM.DecodeChar();
if (NextCh==0)
{
if (!ReadTables())
break;
continue;
}
if (NextCh==2 || NextCh==-1)
break;
if (NextCh==3)
{
if (!ReadVMCodePPM())
break;
continue;
}
if (NextCh==4)
{
unsigned int Distance=0,Length = 0;
bool Failed=false;
for (int I=0;I<4 && !Failed;I++)
{
int Ch=PPM.DecodeChar();
if (Ch==-1)
Failed=true;
else
if (I==3)
Length=(byte)Ch;
else
Distance=(Distance<<8)+(byte)Ch;
}
if (Failed)
break;
CopyString(Length+32,Distance+2);
continue;
}
if (NextCh==5)
{
int Length=PPM.DecodeChar();
if (Length==-1)
break;
CopyString(Length+4,1);
continue;
}
}
Window[UnpPtr++]=Ch;
continue;
}
int Number=DecodeNumber((struct Decode *)&LD);
if (Number<256)
{
Window[UnpPtr++]=(byte)Number;
continue;
}
if (Number>=271)
{
int Length=LDecode[Number-=271]+3;
if ((Bits=LBits[Number])>0)
{
Length+=getbits()>>(16-Bits);
addbits(Bits);
}
int DistNumber=DecodeNumber((struct Decode *)&DD);
unsigned int Distance=DDecode[DistNumber]+1;
if ((Bits=DBits[DistNumber])>0)
{
if (DistNumber>9)
{
if (Bits>4)
{
Distance+=((getbits()>>(20-Bits))<<4);
addbits(Bits-4);
}
if (LowDistRepCount>0)
{
LowDistRepCount--;
Distance+=PrevLowDist;
}
else
{
int LowDist=DecodeNumber((struct Decode *)&LDD);
if (LowDist==16)
{
LowDistRepCount=LOW_DIST_REP_COUNT-1;
Distance+=PrevLowDist;
}
else
{
Distance+=LowDist;
PrevLowDist=LowDist;
}
}
}
else
{
Distance+=getbits()>>(16-Bits);
addbits(Bits);
}
}
if (Distance>=0x2000)
{
Length++;
if (Distance>=0x40000L)
Length++;
}
InsertOldDist(Distance);
InsertLastMatch(Length,Distance);
CopyString(Length,Distance);
continue;
}
if (Number==256)
{
if (!ReadEndOfBlock())
break;
continue;
}
if (Number==257)
{
if (!ReadVMCode())
break;
continue;
}
if (Number==258)
{
if (LastLength!=0)
CopyString(LastLength,LastDist);
continue;
}
if (Number<263)
{
int DistNum=Number-259;
unsigned int Distance=OldDist[DistNum];
for (int I=DistNum;I>0;I--)
OldDist[I]=OldDist[I-1];
OldDist[0]=Distance;
int LengthNumber=DecodeNumber((struct Decode *)&RD);
int Length=LDecode[LengthNumber]+2;
if ((Bits=LBits[LengthNumber])>0)
{
Length+=getbits()>>(16-Bits);
addbits(Bits);
}
InsertLastMatch(Length,Distance);
CopyString(Length,Distance);
continue;
}
if (Number<272)
{
unsigned int Distance=SDDecode[Number-=263]+1;
if ((Bits=SDBits[Number])>0)
{
Distance+=getbits()>>(16-Bits);
addbits(Bits);
}
InsertOldDist(Distance);
InsertLastMatch(2,Distance);
CopyString(2,Distance);
continue;
}
}
UnpWriteBuf();
}
bool Unpack::ReadEndOfBlock()
{
unsigned int BitField=getbits();
bool NewTable,NewFile=false;
if (BitField & 0x8000)
{
NewTable=true;
addbits(1);
}
else
{
NewFile=true;
NewTable=(BitField & 0x4000);
addbits(2);
}
TablesRead=!NewTable;
return !(NewFile || NewTable && !ReadTables());
}
bool Unpack::ReadVMCode()
{
unsigned int FirstByte=getbits()>>8;
addbits(8);
int Length=(FirstByte & 7)+1;
if (Length==7)
{
Length=(getbits()>>8)+7;
addbits(8);
}
else
if (Length==8)
{
Length=getbits();
addbits(16);
}
VMCode.Alloc( Length );
for (int I=0;I<Length;I++)
{
if (InAddr>=ReadTop-1 && !UnpReadBuf() && I<Length-1)
return(false);
VMCode[I]=getbits()>>8;
addbits(8);
}
return(AddVMCode(FirstByte,&VMCode[0],Length));
}
bool Unpack::ReadVMCodePPM()
{
unsigned int FirstByte=PPM.DecodeChar();
if ((int)FirstByte==-1)
return(false);
int Length=(FirstByte & 7)+1;
if (Length==7)
{
int B1=PPM.DecodeChar();
if (B1==-1)
return(false);
Length=B1+7;
}
else
if (Length==8)
{
int B1=PPM.DecodeChar();
if (B1==-1)
return(false);
int B2=PPM.DecodeChar();
if (B2==-1)
return(false);
Length=B1*256+B2;
}
VMCode.Alloc( Length );
for (int I=0;I<Length;I++)
{
int Ch=PPM.DecodeChar();
if (Ch==-1)
return(false);
VMCode[I]=Ch;
}
return(AddVMCode(FirstByte,&VMCode[0],Length));
}
bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
{
// TODO: auto clear object to free bit input on normal return?
Inp.InitBitInput();
memcpy(Inp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize));
VMCode.Reset();
VM.Init();
uint FiltPos;
if (FirstByte & 0x80)
{
FiltPos=RarVM::ReadData(Inp);
if (FiltPos==0)
InitFilters();
else
FiltPos--;
}
else
FiltPos=LastFilter;
if (FiltPos>Filters.Size() || FiltPos>OldFilterLengths.Size())
return(false);
LastFilter=FiltPos;
bool NewFilter=(FiltPos==Filters.Size());
UnpackFilter *Filter;
if (NewFilter)
{
Filters.Add(1);
Filters[Filters.Size()-1]=Filter=new UnpackFilter( error_handler );
if ( !Filter )
rar_out_of_memory( error_handler );
OldFilterLengths.Add(1);
Filter->ExecCount=0;
}
else
{
Filter=Filters[FiltPos];
Filter->ExecCount++;
}
UnpackFilter *StackFilter=new UnpackFilter( error_handler );
if ( !StackFilter )
rar_out_of_memory( error_handler );
int EmptyCount=0;
for (int I2=0;I2<PrgStack.Size();I2++)
{
PrgStack[I2-EmptyCount]=PrgStack[I2];
if (PrgStack[I2]==NULL)
EmptyCount++;
if (EmptyCount>0)
PrgStack[I2]=NULL;
}
if (EmptyCount==0)
{
PrgStack.Add(1);
EmptyCount=1;
}
int StackPos=PrgStack.Size()-EmptyCount;
// TODO: could leak StackFilter before this point
PrgStack[StackPos]=StackFilter;
StackFilter->ExecCount=Filter->ExecCount;
uint BlockStart=RarVM::ReadData(Inp);
if (FirstByte & 0x40)
BlockStart+=258;
StackFilter->BlockStart=(BlockStart+UnpPtr)&MAXWINMASK;
if (FirstByte & 0x20)
StackFilter->BlockLength=RarVM::ReadData(Inp);
else
StackFilter->BlockLength=FiltPos<OldFilterLengths.Size() ? OldFilterLengths[FiltPos]:0;
StackFilter->NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MAXWINMASK)<=BlockStart;
// DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x BlockStart=%08x",UnpPtr,WrPtr,BlockStart);
OldFilterLengths[FiltPos]=StackFilter->BlockLength;
memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR));
StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR;
StackFilter->Prg.InitR[4]=StackFilter->BlockLength;
StackFilter->Prg.InitR[5]=StackFilter->ExecCount;
if (FirstByte & 0x10)
{
unsigned int InitMask=Inp.fgetbits()>>9;
Inp.faddbits(7);
for (int I=0;I<7;I++)
if (InitMask & (1<<I))
StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp);
}
if (NewFilter)
{
uint VMCodeSize=RarVM::ReadData(Inp);
if (VMCodeSize>=0x10000 || VMCodeSize==0)
return(false);
VMCode.Alloc( VMCodeSize );
for (int I=0;I<VMCodeSize;I++)
{
VMCode[I]=Inp.fgetbits()>>8;
Inp.faddbits(8);
}
VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
VMCode.Reset();
}
StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0];
StackFilter->Prg.CmdCount=Filter->Prg.CmdCount;
int StaticDataSize=Filter->Prg.StaticData.Size();
if (StaticDataSize>0 && StaticDataSize<VM_GLOBALMEMSIZE)
{
StackFilter->Prg.StaticData.Add(StaticDataSize);
memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize);
}
if (StackFilter->Prg.GlobalData.Size()<VM_FIXEDGLOBALSIZE)
{
StackFilter->Prg.GlobalData.Reset();
StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE);
}
byte *GlobalData=&StackFilter->Prg.GlobalData[0];
for (int I=0;I<7;I++)
VM.SetValue((uint *)&GlobalData[I*4],StackFilter->Prg.InitR[I]);
VM.SetValue((uint *)&GlobalData[0x1c],StackFilter->BlockLength);
VM.SetValue((uint *)&GlobalData[0x20],0);
VM.SetValue((uint *)&GlobalData[0x2c],StackFilter->ExecCount);
memset(&GlobalData[0x30],0,16);
if (FirstByte & 8)
{
uint DataSize=RarVM::ReadData(Inp);
if (DataSize>=0x10000)
return(false);
unsigned int CurSize=StackFilter->Prg.GlobalData.Size();
if (CurSize<DataSize+VM_FIXEDGLOBALSIZE)
StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize);
byte *GlobalData=&StackFilter->Prg.GlobalData[VM_FIXEDGLOBALSIZE];
for (int I=0;I<DataSize;I++)
{
GlobalData[I]=Inp.fgetbits()>>8;
Inp.faddbits(8);
}
}
return(true);
}
bool Unpack::UnpReadBuf()
{
int DataSize=ReadTop-InAddr;
if (DataSize<0)
return(false);
if (InAddr>BitInput::MAX_SIZE/2)
{
if (DataSize>0)
memmove(InBuf,InBuf+InAddr,DataSize);
InAddr=0;
ReadTop=DataSize;
}
else
DataSize=ReadTop;
int ReadCode=UnpIO->UnpRead(InBuf+DataSize,(BitInput::MAX_SIZE-DataSize)&~0xf);
if (ReadCode>0)
ReadTop+=ReadCode;
ReadBorder=ReadTop-30;
return(ReadCode!=-1);
}
void Unpack::UnpWriteBuf()
{
unsigned int WrittenBorder=WrPtr;
unsigned int WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
for (int I=0;I<PrgStack.Size();I++)
{
UnpackFilter *flt=PrgStack[I];
if (flt==NULL)
continue;
if (flt->NextWindow)
{
flt->NextWindow=false;
continue;
}
unsigned int BlockStart=flt->BlockStart;
unsigned int BlockLength=flt->BlockLength;
if (((BlockStart-WrittenBorder)&MAXWINMASK)<WriteSize)
{
if (WrittenBorder!=BlockStart)
{
UnpWriteArea(WrittenBorder,BlockStart);
WrittenBorder=BlockStart;
WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
}
if (BlockLength<=WriteSize)
{
unsigned int BlockEnd=(BlockStart+BlockLength)&MAXWINMASK;
if (BlockStart<BlockEnd || BlockEnd==0)
VM.SetMemory(0,Window+BlockStart,BlockLength);
else
{
unsigned int FirstPartLength=MAXWINSIZE-BlockStart;
VM.SetMemory(0,Window+BlockStart,FirstPartLength);
VM.SetMemory(FirstPartLength,Window,BlockEnd);
}
VM_PreparedProgram *Prg=&flt->Prg;
ExecuteCode(Prg);
byte *FilteredData=Prg->FilteredData;
unsigned int FilteredDataSize=Prg->FilteredDataSize;
delete PrgStack[I];
PrgStack[I]=NULL;
while (I+1<PrgStack.Size())
{
UnpackFilter *NextFilter=PrgStack[I+1];
if (NextFilter==NULL || NextFilter->BlockStart!=BlockStart ||
NextFilter->BlockLength!=FilteredDataSize || NextFilter->NextWindow)
break;
VM.SetMemory(0,FilteredData,FilteredDataSize);
VM_PreparedProgram *NextPrg=&PrgStack[I+1]->Prg;
ExecuteCode(NextPrg);
FilteredData=NextPrg->FilteredData;
FilteredDataSize=NextPrg->FilteredDataSize;
I++;
delete PrgStack[I];
PrgStack[I]=NULL;
}
UnpIO->UnpWrite(FilteredData,FilteredDataSize);
UnpSomeRead=true;
WrittenFileSize+=FilteredDataSize;
WrittenBorder=BlockEnd;
WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
}
else
{
for (int J=I;J<PrgStack.Size();J++)
{
UnpackFilter *flt=PrgStack[J];
if (flt!=NULL && flt->NextWindow)
flt->NextWindow=false;
}
WrPtr=WrittenBorder;
return;
}
}
}
UnpWriteArea(WrittenBorder,UnpPtr);
WrPtr=UnpPtr;
}
void Unpack::ExecuteCode(VM_PreparedProgram *Prg)
{
if (Prg->GlobalData.Size()>0)
{
Prg->InitR[6]=int64to32(WrittenFileSize);
VM.SetValue((uint *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize));
VM.SetValue((uint *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>31>>1));
VM.Execute(Prg);
}
}
void Unpack::UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr)
{
if (EndPtr!=StartPtr)
UnpSomeRead=true;
if (EndPtr<StartPtr)
{
UnpWriteData(&Window[StartPtr],-StartPtr & MAXWINMASK);
UnpWriteData(Window,EndPtr);
UnpAllBuf=true;
}
else
UnpWriteData(&Window[StartPtr],EndPtr-StartPtr);
}
void Unpack::UnpWriteData(byte *Data,int Size)
{
if (WrittenFileSize>=DestUnpSize)
return;
int WriteSize=Size;
Int64 LeftToWrite=DestUnpSize-WrittenFileSize;
if (WriteSize>LeftToWrite)
WriteSize=int64to32(LeftToWrite);
UnpIO->UnpWrite(Data,WriteSize);
WrittenFileSize+=Size;
}
bool Unpack::ReadTables()
{
byte BitLength[BC];
unsigned char Table[HUFF_TABLE_SIZE];
if (InAddr>ReadTop-25)
if (!UnpReadBuf())
return(false);
faddbits((8-InBit)&7);
unsigned int BitField=fgetbits();
if (BitField & 0x8000)
{
UnpBlockType=BLOCK_PPM;
return(PPM.DecodeInit(this,PPMEscChar));
}
UnpBlockType=BLOCK_LZ;
PrevLowDist=0;
LowDistRepCount=0;
if (!(BitField & 0x4000))
memset(UnpOldTable,0,sizeof(UnpOldTable));
faddbits(2);
for (int I2=0;I2<BC;I2++)
{
int Length=(byte)(fgetbits() >> 12);
faddbits(4);
if (Length==15)
{
int ZeroCount=(byte)(fgetbits() >> 12);
faddbits(4);
if (ZeroCount==0)
BitLength[I2]=15;
else
{
ZeroCount+=2;
while (ZeroCount-- > 0 && I2<sizeof(BitLength)/sizeof(BitLength[0]))
BitLength[I2++]=0;
I2--;
}
}
else
BitLength[I2]=Length;
}
MakeDecodeTables(BitLength,(struct Decode *)&BD,BC);
const int TableSize=HUFF_TABLE_SIZE;
for (int I=0;I<TableSize;)
{
if (InAddr>ReadTop-5)
if (!UnpReadBuf())
return(false);
int Number=DecodeNumber((struct Decode *)&BD);
if (Number<16)
{
Table[I]=(Number+UnpOldTable[I]) & 0xf;
I++;
}
else
if (Number<18)
{
int N;
if (Number==16)
{
N=(fgetbits() >> 13)+3;
faddbits(3);
}
else
{
N=(fgetbits() >> 9)+11;
faddbits(7);
}
while (N-- > 0 && I<TableSize)
{
Table[I]=Table[I-1];
I++;
}
}
else
{
int N;
if (Number==18)
{
N=(fgetbits() >> 13)+3;
faddbits(3);
}
else
{
N=(fgetbits() >> 9)+11;
faddbits(7);
}
while (N-- > 0 && I<TableSize)
Table[I++]=0;
}
}
TablesRead=true;
if (InAddr>ReadTop)
return(false);
MakeDecodeTables(&Table[0],(struct Decode *)&LD,NC);
MakeDecodeTables(&Table[NC],(struct Decode *)&DD,DC);
MakeDecodeTables(&Table[NC+DC],(struct Decode *)&LDD,LDC);
MakeDecodeTables(&Table[NC+DC+LDC],(struct Decode *)&RD,RC);
memcpy(UnpOldTable,Table,sizeof(UnpOldTable));
return(true);
}
void Unpack::UnpInitData(int Solid)
{
if (!Solid)
{
TablesRead=false;
memset(OldDist,0,sizeof(OldDist));
OldDistPtr=0;
LastDist=LastLength=0;
// memset(Window,0,MAXWINSIZE);
memset(UnpOldTable,0,sizeof(UnpOldTable));
UnpPtr=WrPtr=0;
PPMEscChar=2;
InitFilters();
}
InitBitInput();
PPMError=false;
WrittenFileSize=0;
ReadTop=0;
ReadBorder=0;
UnpInitData20(Solid);
}
void Unpack::InitFilters()
{
OldFilterLengths.Reset();
LastFilter=0;
for (int I2=0;I2<Filters.Size();I2++)
delete Filters[I2];
Filters.Reset();
for (int I=0;I<PrgStack.Size();I++)
delete PrgStack[I];
PrgStack.Reset();
}
void Unpack::MakeDecodeTables(unsigned char *LenTab,struct Decode *Dec,int Size)
{
int LenCount[16],TmpPos[16],I;
long M,N;
memset(LenCount,0,sizeof(LenCount));
memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
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;
}

View File

@ -1,215 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#ifndef _RAR_UNPACK_
#define _RAR_UNPACK_
enum BLOCK_TYPES {BLOCK_LZ,BLOCK_PPM};
struct Decode
{
unsigned int MaxNum;
unsigned int DecodeLen[16];
unsigned int DecodePos[16];
unsigned int DecodeNum[2];
};
struct LitDecode
{
unsigned int MaxNum;
unsigned int DecodeLen[16];
unsigned int DecodePos[16];
unsigned int DecodeNum[NC];
};
struct DistDecode
{
unsigned int MaxNum;
unsigned int DecodeLen[16];
unsigned int DecodePos[16];
unsigned int DecodeNum[DC];
};
struct LowDistDecode
{
unsigned int MaxNum;
unsigned int DecodeLen[16];
unsigned int DecodePos[16];
unsigned int DecodeNum[LDC];
};
struct RepDecode
{
unsigned int MaxNum;
unsigned int DecodeLen[16];
unsigned int DecodePos[16];
unsigned int DecodeNum[RC];
};
struct BitDecode
{
unsigned int MaxNum;
unsigned int DecodeLen[16];
unsigned int DecodePos[16];
unsigned int DecodeNum[BC];
};
struct UnpackFilter : Rar_Allocator
{
unsigned int BlockStart;
unsigned int BlockLength;
unsigned int ExecCount;
bool NextWindow;
VM_PreparedProgram Prg;
UnpackFilter( Rar_Error_Handler* eh ) : Prg( eh ) { }
};
/***************************** Unpack v 2.0 *********************************/
struct MultDecode
{
unsigned int MaxNum;
unsigned int DecodeLen[16];
unsigned int DecodePos[16];
unsigned int DecodeNum[MC20];
};
struct AudioVariables
{
int K1,K2,K3,K4,K5;
int D1,D2,D3,D4;
int LastDelta;
unsigned int Dif[11];
unsigned int ByteCount;
int LastChar;
};
/***************************** Unpack v 2.0 *********************************/
class Unpack : private BitInput {
private:
void Unpack29(bool Solid);
bool UnpReadBuf();
void UnpWriteBuf();
void ExecuteCode(VM_PreparedProgram *Prg);
void UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr);
void UnpWriteData(byte *Data,int Size);
bool ReadTables();
void MakeDecodeTables(unsigned char *LenTab,struct Decode *Dec,int Size);
int DecodeNumber(struct Decode *Dec);
void CopyString();
inline void InsertOldDist(unsigned int Distance);
inline void InsertLastMatch(unsigned int Length,unsigned int Distance);
void UnpInitData(int Solid);
void CopyString(unsigned int Length,unsigned int Distance);
bool ReadEndOfBlock();
bool ReadVMCode();
bool ReadVMCodePPM();
bool AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize);
void InitFilters();
Rar_Array<byte> VMCode; // here to avoid leaks
BitInput Inp; // here to avoid leaks
Rar_Extractor_Impl *UnpIO;
public:
ModelPPM PPM;
private:
int PPMEscChar;
RarVM VM;
Rar_Array<UnpackFilter*> Filters;
Rar_Array<UnpackFilter*> PrgStack;
Rar_Array<int> OldFilterLengths;
int LastFilter;
bool TablesRead;
struct LitDecode LD;
struct DistDecode DD;
struct LowDistDecode LDD;
struct RepDecode RD;
struct BitDecode BD;
unsigned int OldDist[4],OldDistPtr;
unsigned int LastDist,LastLength;
unsigned int UnpPtr,WrPtr;
int ReadTop;
int ReadBorder;
unsigned char UnpOldTable[HUFF_TABLE_SIZE];
int UnpBlockType;
byte *Window;
bool ExternalWindow;
Int64 DestUnpSize;
bool Suspended;
bool UnpAllBuf;
bool UnpSomeRead;
Int64 WrittenFileSize;
bool FileExtracted;
bool PPMError;
int PrevLowDist,LowDistRepCount;
/***************************** Unpack v 1.5 *********************************/
void Unpack15(bool Solid);
void ShortLZ();
void LongLZ();
void HuffDecode();
void GetFlagsBuf();
void OldUnpInitData(int Solid);
void InitHuff();
void CorrHuff(unsigned int *CharSet,unsigned int *NumToPlace);
void OldCopyString(unsigned int Distance,unsigned int Length);
unsigned int DecodeNum(int Num,unsigned int StartPos,
unsigned int *DecTab,unsigned int *PosTab);
void OldUnpWriteBuf();
unsigned int ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
unsigned int Place[256],PlaceA[256],PlaceB[256],PlaceC[256];
unsigned int NToPl[256],NToPlB[256],NToPlC[256];
unsigned int FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
int Buf60,NumHuf,StMode,LCount,FlagsCnt;
unsigned int Nhfb,Nlzb,MaxDist3;
/***************************** Unpack v 1.5 *********************************/
/***************************** Unpack v 2.0 *********************************/
void Unpack20(bool Solid);
struct MultDecode MD[4];
unsigned char UnpOldTable20[MC20*4];
int UnpAudioBlock,UnpChannels,UnpCurChannel,UnpChannelDelta;
void CopyString20(unsigned int Length,unsigned int Distance);
bool ReadTables20();
void UnpInitData20(int Solid);
void ReadLastTables();
byte DecodeAudio(int Delta);
struct AudioVariables AudV[4];
/***************************** Unpack v 2.0 *********************************/
Rar_Error_Handler* error_handler;
public:
Unpack(Rar_Extractor_Impl *DataIO, Rar_Error_Handler* );
~Unpack();
void Init(byte *Window=NULL);
void DoUnpack(int Method,bool Solid);
bool IsFileExtracted() {return(FileExtracted);}
void SetDestSize(Int64 DestSize) {DestUnpSize=DestSize;FileExtracted=false;}
void SetSuspended(bool Suspended) {Unpack::Suspended=Suspended;}
unsigned int GetChar()
{
if (InAddr>BitInput::MAX_SIZE-30)
UnpReadBuf();
return(InBuf[InAddr++]);
}
};
#endif

View File

@ -1,519 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#include "rar.hpp"
#if defined (__MWERKS__) && __MWERKS__ < 0x3200
// higher level breaks code in CW4 (but not in CW9)
#pragma optimization_level 1
#endif
#define STARTL1 2
static unsigned int DecL1[]={0x8000,0xa000,0xc000,0xd000,0xe000,0xea00,
0xee00,0xf000,0xf200,0xf200,0xffff};
static unsigned int PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32};
#define STARTL2 3
static unsigned int DecL2[]={0xa000,0xc000,0xd000,0xe000,0xea00,0xee00,
0xf000,0xf200,0xf240,0xffff};
static unsigned int PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36};
#define STARTHF0 4
static unsigned int DecHf0[]={0x8000,0xc000,0xe000,0xf200,0xf200,0xf200,
0xf200,0xf200,0xffff};
static unsigned int PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33};
#define STARTHF1 5
static unsigned int DecHf1[]={0x2000,0xc000,0xe000,0xf000,0xf200,0xf200,
0xf7e0,0xffff};
static unsigned int PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127};
#define STARTHF2 5
static unsigned int DecHf2[]={0x1000,0x2400,0x8000,0xc000,0xfa00,0xffff,
0xffff,0xffff};
static unsigned int PosHf2[]={0,0,0,0,0,0,2,7,53,117,233,0,0};
#define STARTHF3 6
static unsigned int DecHf3[]={0x800,0x2400,0xee00,0xfe80,0xffff,0xffff,
0xffff};
static unsigned int PosHf3[]={0,0,0,0,0,0,0,2,16,218,251,0,0};
#define STARTHF4 8
static unsigned int DecHf4[]={0xff00,0xffff,0xffff,0xffff,0xffff,0xffff};
static unsigned int PosHf4[]={0,0,0,0,0,0,0,0,0,255,0,0,0};
void Unpack::Unpack15(bool Solid)
{
if (Suspended)
UnpPtr=WrPtr;
else
{
UnpInitData(Solid);
OldUnpInitData(Solid);
UnpReadBuf();
if (!Solid)
{
InitHuff();
UnpPtr=0;
}
else
UnpPtr=WrPtr;
--DestUnpSize;
}
if (DestUnpSize>=0)
{
GetFlagsBuf();
FlagsCnt=8;
}
while (DestUnpSize>=0)
{
UnpPtr&=MAXWINMASK;
if (InAddr>ReadTop-30 && !UnpReadBuf())
break;
if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr)
{
OldUnpWriteBuf();
if (Suspended)
return;
}
if (StMode)
{
HuffDecode();
continue;
}
if (--FlagsCnt < 0)
{
GetFlagsBuf();
FlagsCnt=7;
}
if (FlagBuf & 0x80)
{
FlagBuf<<=1;
if (Nlzb > Nhfb)
LongLZ();
else
HuffDecode();
}
else
{
FlagBuf<<=1;
if (--FlagsCnt < 0)
{
GetFlagsBuf();
FlagsCnt=7;
}
if (FlagBuf & 0x80)
{
FlagBuf<<=1;
if (Nlzb > Nhfb)
HuffDecode();
else
LongLZ();
}
else
{
FlagBuf<<=1;
ShortLZ();
}
}
}
OldUnpWriteBuf();
}
void Unpack::OldUnpWriteBuf()
{
if (UnpPtr!=WrPtr)
UnpSomeRead=true;
if (UnpPtr<WrPtr)
{
UnpIO->UnpWrite(&Window[WrPtr],-WrPtr & MAXWINMASK);
UnpIO->UnpWrite(Window,UnpPtr);
UnpAllBuf=true;
}
else
UnpIO->UnpWrite(&Window[WrPtr],UnpPtr-WrPtr);
WrPtr=UnpPtr;
}
void Unpack::ShortLZ()
{
static unsigned int ShortLen1[]={1,3,4,4,5,6,7,8,8,4,4,5,6,6,4,0};
static unsigned int ShortXor1[]={0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,
0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0};
static unsigned int ShortLen2[]={2,3,3,3,4,4,5,6,6,4,4,5,6,6,4,0};
static unsigned int ShortXor2[]={0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,
0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0};
unsigned int Length,SaveLength;
unsigned int LastDistance;
unsigned int Distance;
int DistancePlace;
NumHuf=0;
unsigned int BitField=fgetbits();
if (LCount==2)
{
faddbits(1);
if (BitField >= 0x8000)
{
OldCopyString((unsigned int)LastDist,LastLength);
return;
}
BitField <<= 1;
LCount=0;
}
BitField>>=8;
ShortLen1[1]=ShortLen2[3]=Buf60+3;
if (AvrLn1<37)
{
for (Length=0;;Length++)
if (((BitField^ShortXor1[Length]) & (~(0xff>>ShortLen1[Length])))==0)
break;
faddbits(ShortLen1[Length]);
}
else
{
for (Length=0;;Length++)
if (((BitField^ShortXor2[Length]) & (~(0xff>>ShortLen2[Length])))==0)
break;
faddbits(ShortLen2[Length]);
}
if (Length >= 9)
{
if (Length == 9)
{
LCount++;
OldCopyString((unsigned int)LastDist,LastLength);
return;
}
if (Length == 14)
{
LCount=0;
Length=DecodeNum(fgetbits(),STARTL2,DecL2,PosL2)+5;
Distance=(fgetbits()>>1) | 0x8000;
faddbits(15);
LastLength=Length;
LastDist=Distance;
OldCopyString(Distance,Length);
return;
}
LCount=0;
SaveLength=Length;
Distance=OldDist[(OldDistPtr-(Length-9)) & 3];
Length=DecodeNum(fgetbits(),STARTL1,DecL1,PosL1)+2;
if (Length==0x101 && SaveLength==10)
{
Buf60 ^= 1;
return;
}
if (Distance > 256)
Length++;
if (Distance >= MaxDist3)
Length++;
OldDist[OldDistPtr++]=Distance;
OldDistPtr = OldDistPtr & 3;
LastLength=Length;
LastDist=Distance;
OldCopyString(Distance,Length);
return;
}
LCount=0;
AvrLn1 += Length;
AvrLn1 -= AvrLn1 >> 4;
DistancePlace=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2) & 0xff;
Distance=ChSetA[DistancePlace];
if (--DistancePlace != -1)
{
PlaceA[Distance]--;
LastDistance=ChSetA[DistancePlace];
PlaceA[LastDistance]++;
ChSetA[DistancePlace+1]=LastDistance;
ChSetA[DistancePlace]=Distance;
}
Length+=2;
OldDist[OldDistPtr++] = ++Distance;
OldDistPtr = OldDistPtr & 3;
LastLength=Length;
LastDist=Distance;
OldCopyString(Distance,Length);
}
void Unpack::LongLZ()
{
unsigned int Length;
unsigned int Distance;
unsigned int DistancePlace,NewDistancePlace;
unsigned int OldAvr2,OldAvr3;
NumHuf=0;
Nlzb+=16;
if (Nlzb > 0xff)
{
Nlzb=0x90;
Nhfb >>= 1;
}
OldAvr2=AvrLn2;
unsigned int BitField=fgetbits();
if (AvrLn2 >= 122)
Length=DecodeNum(BitField,STARTL2,DecL2,PosL2);
else
if (AvrLn2 >= 64)
Length=DecodeNum(BitField,STARTL1,DecL1,PosL1);
else
if (BitField < 0x100)
{
Length=BitField;
faddbits(16);
}
else
{
for (Length=0;((BitField<<Length)&0x8000)==0;Length++)
;
faddbits(Length+1);
}
AvrLn2 += Length;
AvrLn2 -= AvrLn2 >> 5;
BitField=fgetbits();
if (AvrPlcB > 0x28ff)
DistancePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
else
if (AvrPlcB > 0x6ff)
DistancePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
else
DistancePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
AvrPlcB += DistancePlace;
AvrPlcB -= AvrPlcB >> 8;
while (1)
{
Distance = ChSetB[DistancePlace & 0xff];
NewDistancePlace = NToPlB[Distance++ & 0xff]++;
if (!(Distance & 0xff))
CorrHuff(ChSetB,NToPlB);
else
break;
}
ChSetB[DistancePlace]=ChSetB[NewDistancePlace];
ChSetB[NewDistancePlace]=Distance;
Distance=((Distance & 0xff00) | (fgetbits() >> 8)) >> 1;
faddbits(7);
OldAvr3=AvrLn3;
if (Length!=1 && Length!=4)
if (Length==0 && Distance <= MaxDist3)
{
AvrLn3++;
AvrLn3 -= AvrLn3 >> 8;
}
else
if (AvrLn3 > 0)
AvrLn3--;
Length+=3;
if (Distance >= MaxDist3)
Length++;
if (Distance <= 256)
Length+=8;
if (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40)
MaxDist3=0x7f00;
else
MaxDist3=0x2001;
OldDist[OldDistPtr++]=Distance;
OldDistPtr = OldDistPtr & 3;
LastLength=Length;
LastDist=Distance;
OldCopyString(Distance,Length);
}
void Unpack::HuffDecode()
{
unsigned int CurByte,NewBytePlace;
unsigned int Length;
unsigned int Distance;
int BytePlace;
unsigned int BitField=fgetbits();
if (AvrPlc > 0x75ff)
BytePlace=DecodeNum(BitField,STARTHF4,DecHf4,PosHf4);
else
if (AvrPlc > 0x5dff)
BytePlace=DecodeNum(BitField,STARTHF3,DecHf3,PosHf3);
else
if (AvrPlc > 0x35ff)
BytePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
else
if (AvrPlc > 0x0dff)
BytePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
else
BytePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
BytePlace&=0xff;
if (StMode)
{
if (BytePlace==0 && BitField > 0xfff)
BytePlace=0x100;
if (--BytePlace==-1)
{
BitField=fgetbits();
faddbits(1);
if (BitField & 0x8000)
{
NumHuf=StMode=0;
return;
}
else
{
Length = (BitField & 0x4000) ? 4 : 3;
faddbits(1);
Distance=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2);
Distance = (Distance << 5) | (fgetbits() >> 11);
faddbits(5);
OldCopyString(Distance,Length);
return;
}
}
}
else
if (NumHuf++ >= 16 && FlagsCnt==0)
StMode=1;
AvrPlc += BytePlace;
AvrPlc -= AvrPlc >> 8;
Nhfb+=16;
if (Nhfb > 0xff)
{
Nhfb=0x90;
Nlzb >>= 1;
}
Window[UnpPtr++]=(byte)(ChSet[BytePlace]>>8);
--DestUnpSize;
while (1)
{
CurByte=ChSet[BytePlace];
NewBytePlace=NToPl[CurByte++ & 0xff]++;
if ((CurByte & 0xff) > 0xa1)
CorrHuff(ChSet,NToPl);
else
break;
}
ChSet[BytePlace]=ChSet[NewBytePlace];
ChSet[NewBytePlace]=CurByte;
}
void Unpack::GetFlagsBuf()
{
unsigned int Flags,NewFlagsPlace;
unsigned int FlagsPlace=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2);
while (1)
{
Flags=ChSetC[FlagsPlace];
FlagBuf=Flags>>8;
NewFlagsPlace=NToPlC[Flags++ & 0xff]++;
if ((Flags & 0xff) != 0)
break;
CorrHuff(ChSetC,NToPlC);
}
ChSetC[FlagsPlace]=ChSetC[NewFlagsPlace];
ChSetC[NewFlagsPlace]=Flags;
}
void Unpack::OldUnpInitData(int Solid)
{
if (!Solid)
{
AvrPlcB=AvrLn1=AvrLn2=AvrLn3=NumHuf=Buf60=0;
AvrPlc=0x3500;
MaxDist3=0x2001;
Nhfb=Nlzb=0x80;
}
FlagsCnt=0;
FlagBuf=0;
StMode=0;
LCount=0;
ReadTop=0;
}
void Unpack::InitHuff()
{
for (unsigned int I=0;I<256;I++)
{
Place[I]=PlaceA[I]=PlaceB[I]=I;
PlaceC[I]=(~I+1) & 0xff;
ChSet[I]=ChSetB[I]=I<<8;
ChSetA[I]=I;
ChSetC[I]=((~I+1) & 0xff)<<8;
}
memset(NToPl,0,sizeof(NToPl));
memset(NToPlB,0,sizeof(NToPlB));
memset(NToPlC,0,sizeof(NToPlC));
CorrHuff(ChSetB,NToPlB);
}
void Unpack::CorrHuff(unsigned int *CharSet,unsigned int *NumToPlace)
{
int I,J;
for (I=7;I>=0;I--)
for (J=0;J<32;J++,CharSet++)
*CharSet=(*CharSet & ~0xff) | I;
memset(NumToPlace,0,sizeof(NToPl));
for (I=6;I>=0;I--)
NumToPlace[I]=(7-I)*32;
}
void Unpack::OldCopyString(unsigned int Distance,unsigned int Length)
{
DestUnpSize-=Length;
while (Length--)
{
Window[UnpPtr]=Window[(UnpPtr-Distance) & MAXWINMASK];
UnpPtr=(UnpPtr+1) & MAXWINMASK;
}
}
unsigned int Unpack::DecodeNum(int Num,unsigned int StartPos,
unsigned int *DecTab,unsigned int *PosTab)
{
int I;
for (Num&=0xfff0,I=0;DecTab[I]<=Num;I++)
StartPos++;
faddbits(StartPos);
return(((Num-(I ? DecTab[I-1]:0))>>(16-StartPos))+PosTab[StartPos]);
}

View File

@ -1,378 +0,0 @@
// File_Extractor 0.4.2
// This source code is a heavily modified version based on the unrar package.
// It may not be used to develop a RAR (WinRAR) compatible archiver.
// See unrar_license.txt for copyright and licensing.
#include "rar.hpp"
#if defined (__MWERKS__) && __MWERKS__ < 0x3200
// higher level breaks code in CW4 (but not in CW9)
#pragma optimization_level 1
#endif
void Unpack::CopyString20(unsigned int Length,unsigned int Distance)
{
LastDist=OldDist[OldDistPtr++ & 3]=Distance;
LastLength=Length;
DestUnpSize-=Length;
unsigned int DestPtr=UnpPtr-Distance;
if (DestPtr<MAXWINSIZE-300 && UnpPtr<MAXWINSIZE-300)
{
Window[UnpPtr++]=Window[DestPtr++];
Window[UnpPtr++]=Window[DestPtr++];
while (Length>2)
{
Length--;
Window[UnpPtr++]=Window[DestPtr++];
}
}
else
while (Length--)
{
Window[UnpPtr]=Window[DestPtr++ & MAXWINMASK];
UnpPtr=(UnpPtr+1) & MAXWINMASK;
}
}
void Unpack::Unpack20(bool Solid)
{
static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
static int DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
static unsigned char DBits[]= {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6};
unsigned int Bits;
if (Suspended)
UnpPtr=WrPtr;
else
{
UnpInitData(Solid);
if (!UnpReadBuf())
return;
if (!Solid)
if (!ReadTables20())
return;
--DestUnpSize;
}
while ( DestUnpSize >= 0 )
{
UnpPtr&=MAXWINMASK;
if (InAddr>ReadTop-30)
if (!UnpReadBuf())
break;
if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr)
{
OldUnpWriteBuf();
if (Suspended)
return;
}
if (UnpAudioBlock)
{
int AudioNumber=DecodeNumber((struct Decode *)&MD[UnpCurChannel]);
if (AudioNumber==256)
{
if (!ReadTables20())
break;
continue;
}
Window[UnpPtr++]=DecodeAudio(AudioNumber);
if (++UnpCurChannel==UnpChannels)
UnpCurChannel=0;
--DestUnpSize;
continue;
}
int Number=DecodeNumber((struct Decode *)&LD);
if (Number<256)
{
Window[UnpPtr++]=(byte)Number;
--DestUnpSize;
continue;
}
if (Number>269)
{
int Length=LDecode[Number-=270]+3;
if ((Bits=LBits[Number])>0)
{
Length+=getbits()>>(16-Bits);
addbits(Bits);
}
int DistNumber=DecodeNumber((struct Decode *)&DD);
unsigned int Distance=DDecode[DistNumber]+1;
if ((Bits=DBits[DistNumber])>0)
{
Distance+=getbits()>>(16-Bits);
addbits(Bits);
}
if (Distance>=0x2000)
{
Length++;
if (Distance>=0x40000L)
Length++;
}
CopyString20(Length,Distance);
continue;
}
if (Number==269)
{
if (!ReadTables20())
break;
continue;
}
if (Number==256)
{
CopyString20(LastLength,LastDist);
continue;
}
if (Number<261)
{
unsigned int Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
int LengthNumber=DecodeNumber((struct Decode *)&RD);
int Length=LDecode[LengthNumber]+2;
if ((Bits=LBits[LengthNumber])>0)
{
Length+=getbits()>>(16-Bits);
addbits(Bits);
}
if (Distance>=0x101)
{
Length++;
if (Distance>=0x2000)
{
Length++;
if (Distance>=0x40000)
Length++;
}
}
CopyString20(Length,Distance);
continue;
}
if (Number<270)
{
unsigned int Distance=SDDecode[Number-=261]+1;
if ((Bits=SDBits[Number])>0)
{
Distance+=getbits()>>(16-Bits);
addbits(Bits);
}
CopyString20(2,Distance);
continue;
}
}
ReadLastTables();
OldUnpWriteBuf();
}
bool Unpack::ReadTables20()
{
byte BitLength[BC20];
unsigned char Table[MC20*4];
int TableSize,N,I;
if (InAddr>ReadTop-25)
if (!UnpReadBuf())
return(false);
unsigned int BitField=getbits();
UnpAudioBlock=(BitField & 0x8000);
if (!(BitField & 0x4000))
memset(UnpOldTable20,0,sizeof(UnpOldTable20));
addbits(2);
if (UnpAudioBlock)
{
UnpChannels=((BitField>>12) & 3)+1;
if (UnpCurChannel>=UnpChannels)
UnpCurChannel=0;
addbits(2);
TableSize=MC20*UnpChannels;
}
else
TableSize=NC20+DC20+RC20;
for (I=0;I<BC20;I++)
{
BitLength[I]=(byte)(getbits() >> 12);
addbits(4);
}
MakeDecodeTables(BitLength,(struct Decode *)&BD,BC20);
I=0;
while (I<TableSize)
{
if (InAddr>ReadTop-5)
if (!UnpReadBuf())
return(false);
int Number=DecodeNumber((struct Decode *)&BD);
if (Number<16)
{
Table[I]=(Number+UnpOldTable20[I]) & 0xf;
I++;
}
else
if (Number==16)
{
N=(getbits() >> 14)+3;
addbits(2);
while (N-- > 0 && I<TableSize)
{
Table[I]=Table[I-1];
I++;
}
}
else
{
if (Number==17)
{
N=(getbits() >> 13)+3;
addbits(3);
}
else
{
N=(getbits() >> 9)+11;
addbits(7);
}
while (N-- > 0 && I<TableSize)
Table[I++]=0;
}
}
if (InAddr>ReadTop)
return(true);
if (UnpAudioBlock)
for (I=0;I<UnpChannels;I++)
MakeDecodeTables(&Table[I*MC20],(struct Decode *)&MD[I],MC20);
else
{
MakeDecodeTables(&Table[0],(struct Decode *)&LD,NC20);
MakeDecodeTables(&Table[NC20],(struct Decode *)&DD,DC20);
MakeDecodeTables(&Table[NC20+DC20],(struct Decode *)&RD,RC20);
}
memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
return(true);
}
void Unpack::ReadLastTables()
{
if (ReadTop>=InAddr+5)
if (UnpAudioBlock)
{
if (DecodeNumber((struct Decode *)&MD[UnpCurChannel])==256)
ReadTables20();
}
else
if (DecodeNumber((struct Decode *)&LD)==269)
ReadTables20();
}
void Unpack::UnpInitData20(int Solid)
{
if (!Solid)
{
UnpChannelDelta=UnpCurChannel=0;
UnpChannels=1;
memset(AudV,0,sizeof(AudV));
memset(UnpOldTable20,0,sizeof(UnpOldTable20));
}
}
byte Unpack::DecodeAudio(int Delta)
{
struct AudioVariables *V=&AudV[UnpCurChannel];
V->ByteCount++;
V->D4=V->D3;
V->D3=V->D2;
V->D2=V->LastDelta-V->D1;
V->D1=V->LastDelta;
int PCh=8*V->LastChar+V->K1*V->D1+V->K2*V->D2+V->K3*V->D3+V->K4*V->D4+V->K5*UnpChannelDelta;
PCh=(PCh>>3) & 0xFF;
unsigned int Ch=PCh-Delta;
int D=((signed char)Delta)<<3;
V->Dif[0]+=abs(D);
V->Dif[1]+=abs(D-V->D1);
V->Dif[2]+=abs(D+V->D1);
V->Dif[3]+=abs(D-V->D2);
V->Dif[4]+=abs(D+V->D2);
V->Dif[5]+=abs(D-V->D3);
V->Dif[6]+=abs(D+V->D3);
V->Dif[7]+=abs(D-V->D4);
V->Dif[8]+=abs(D+V->D4);
V->Dif[9]+=abs(D-UnpChannelDelta);
V->Dif[10]+=abs(D+UnpChannelDelta);
UnpChannelDelta=V->LastDelta=(signed char)(Ch-V->LastChar);
V->LastChar=Ch;
if ((V->ByteCount & 0x1F)==0)
{
unsigned int MinDif=V->Dif[0],NumMinDif=0;
V->Dif[0]=0;
for (int I=1;I<sizeof(V->Dif)/sizeof(V->Dif[0]);I++)
{
if (V->Dif[I]<MinDif)
{
MinDif=V->Dif[I];
NumMinDif=I;
}
V->Dif[I]=0;
}
switch(NumMinDif)
{
case 1:
if (V->K1>=-16)
V->K1--;
break;
case 2:
if (V->K1<16)
V->K1++;
break;
case 3:
if (V->K2>=-16)
V->K2--;
break;
case 4:
if (V->K2<16)
V->K2++;
break;
case 5:
if (V->K3>=-16)
V->K3--;
break;
case 6:
if (V->K3<16)
V->K3++;
break;
case 7:
if (V->K4>=-16)
V->K4--;
break;
case 8:
if (V->K4<16)
V->K4++;
break;
case 9:
if (V->K5>=-16)
V->K5--;
break;
case 10:
if (V->K5<16)
V->K5++;
break;
}
}
return((byte)Ch);
}

View File

@ -1,41 +0,0 @@
****** ***** ****** unRAR - free utility for RAR archives
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
****** ******* ****** License for use and distribution of
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
** ** ** ** ** ** FREE portable version
~~~~~~~~~~~~~~~~~~~~~
The source code of unRAR utility is freeware. This means:
1. All copyrights to RAR and the utility unRAR are exclusively
owned by the author - Alexander Roshal.
2. The unRAR sources may be used in any software to handle RAR
archives without limitations free of charge, but cannot be used
to re-create the RAR compression algorithm, which is proprietary.
Distribution of modified unRAR sources in separate form or as a
part of other software is permitted, provided that it is clearly
stated in the documentation and source comments that the code may
not be used to develop a RAR (WinRAR) compatible archiver.
3. The unRAR utility may be freely distributed. No person or company
may charge a fee for the distribution of unRAR without written
permission from the copyright holder.
4. THE RAR ARCHIVER AND THE UNRAR UTILITY ARE DISTRIBUTED "AS IS".
NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT
YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS,
DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING
OR MISUSING THIS SOFTWARE.
5. Installing and using the unRAR utility signifies acceptance of
these terms and conditions of the license.
6. If you don't agree with terms of the license you must remove
unRAR files from your storage devices and cease to use the
utility.
Thank you for your interest in RAR and unRAR.
Alexander L. Roshal

View File

@ -27,7 +27,6 @@ extern "C" {
#ifdef HAS_FILE_EXTRACTOR
#include <Zip_Extractor.h>
#include <Rar_Extractor.h>
#include <Zip7_Extractor.h>
#endif
@ -544,19 +543,6 @@ bool utilIsZipFile(const char *file)
}
#ifdef HAS_FILE_EXTRACTOR
bool utilIsRarFile(const char *file)
{
if(strlen(file) > 4) {
const char * p = strrchr(file,'.');
if(p != NULL) {
if(_stricmp(p, ".rar") == 0)
return true;
}
}
return false;
}
bool utilIs7ZipFile(const char *file)
{
@ -608,8 +594,7 @@ IMAGE_TYPE utilFindType(const char *file)
#ifdef HAS_FILE_EXTRACTOR
int type = -1;
if (utilIsZipFile(file)) type = 0;
else if (utilIsRarFile(file)) type = 1;
else if (utilIs7ZipFile(file)) type = 2;
else if (utilIs7ZipFile(file)) type = 1;
if(type >= 0) {
@ -618,8 +603,7 @@ IMAGE_TYPE utilFindType(const char *file)
switch (type) {
case 0: ex = new Zip_Extractor; break;
case 1: ex = new Rar_Extractor; break;
case 2: ex = new Zip7_Extractor; break;
case 1: ex = new Zip7_Extractor; break;
default: type = -1; break;
}
@ -763,8 +747,7 @@ static u8 *utilLoadFromFE(const char *file,
switch (type) {
case 0: ex = new Zip_Extractor; break;
case 1: ex = new Rar_Extractor; break;
case 2: ex = new Zip7_Extractor; break;
case 1: ex = new Zip7_Extractor; break;
default: type = -1; break;
}
@ -1007,8 +990,7 @@ u8 *utilLoad(const char *file,
#ifdef HAS_FILE_EXTRACTOR
int type = -1;
if (utilIsZipFile(file)) type = 0;
else if (utilIsRarFile(file)) type = 1;
else if (utilIs7ZipFile(file)) type = 2;
else if (utilIs7ZipFile(file)) type = 1;
if(type>=0) {
return utilLoadFromFE(file, type, accept, data, size);
@ -1020,11 +1002,6 @@ u8 *utilLoad(const char *file,
if(utilIsGzipFile(file)) {
return utilLoadGzipFile(file, accept, data, size);
}
#if 0
if(utilIsRarFile(file)) {
return utilLoadRarFile(file, accept, data, size);
}
#endif
u8 *image = data;